﻿'Description:通用查询类
'Copyright (c) : 通力凯顿（北京）系统集成有限公司
'Writer:Yangsj
'create Date:2017-4-13
'Rewriter:
'Rewrite Date:
Imports BusinessRule.DTO
Imports BusinessRule.IBusiness
Imports DatabaseAccess.DBUtility
Imports Camstar.WebClient.WebServicesProxy.InSiteWebServices
Imports System.Data
Imports System.Text
Imports External.APICalling
Imports System.Data.OracleClient
Imports BusinessRule.Common
Imports DatabaseAccess.IDAL
Imports DatabaseAccess.DALFactory

Public Class uLMSCommonBusiness
    Implements uLMSCommonIBusiness

    Private dal As IOracleDAL = uMESDalContext.instance.GetDalObject()
    ''' <summary>
    ''' 获取人员列表根据角色
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEmplyeeListByRole(ByVal strRoleName As String, ByVal strFactoryID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetEmplyeeListByRole
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT E.EMPLOYEEID, E.EMPLOYEENAME,E.FULLNAME,sv.workcenterid") 'add by tianFW 2018年6月21日 添加对该工艺员的工区信息查询
        sb.AppendLine("FROM EMPLOYEE E")
        sb.AppendLine("LEFT JOIN EMPLOYEEROLE ER  ON ER.EMPLOYEEID = E.EMPLOYEEID")
        sb.AppendLine("LEFT JOIN ROLEDEF R  ON R.ROLEID = ER.ROLEID")
        sb.AppendLine("LEFT JOIN SESSIONVALUES SV ON SV.SESSIONVALUESID = E.SESSIONVALUESID")
        sb.AppendFormat(" WHERE R.ROLENAME = '{0}' AND SV.FACTORYID = '{1}'", strRoleName, strFactoryID)
        sb.AppendLine(" ORDER BY E.FULLNAME")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetEmplyeeListByRole = New DataTable
        Else
            GetEmplyeeListByRole = dt
        End If
    End Function
    ''' <summary>
    ''' 获取企业下的所有工厂
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetFactory(ByVal para As System.Collections.Generic.Dictionary(Of String, String)) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetFactory
        GetFactory = New DataTable
        'modify tianFW 增加对分厂分厂去向属性的查询 2018年4月27日
        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT FA.*")
        strSql.AppendLine("FROM FACTORY FA")
        If para.ContainsKey("FactoryGone") Then
            strSql.AppendLine("LEFT JOIN USERATTRIBUTE UA ON UA.PARENTID = FA.FACTORYID AND UA.USERATTRIBUTENAME = '去向分厂'")
        End If
        strSql.AppendLine("WHERE FA.ENTERPRISEID IS NOT NULL")
        If para.ContainsKey("FactoryGone") Then
            strSql.AppendLine("AND UA.ATTRIBUTEVALUE='是'")
        End If
        GetFactory = DatabaseHelper.Query_ReturnDatTable(strSql.ToString())
    End Function
    ''' <summary>
    ''' 获取机型列表
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetProductFamily(ByVal para As System.Collections.Generic.Dictionary(Of String, String)) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetProductFamily
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT PF.PRODUCTFAMILYNAME,PF.PRODUCTFAMILYID,PF.FAMILYTYPE")
        sb.AppendLine("FROM PRODUCTFAMILY PF")
        If para.ContainsKey("FamilyType") Then
            sb.AppendFormat(" WHERE PF.FAMILYTYPE = '{0}' ", para("FamilyType"))
        ElseIf para.ContainsKey("FamilyName") Then
            sb.AppendFormat(" WHERE PF.PRODUCTFAMILYNAME = '{0}' ", para("FamilyName"))
        End If
        sb.AppendLine(" ORDER BY PF.PRODUCTFAMILYNAME") 'add tianFW 2018年3月20日 机型按首字母排序
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If dt Is Nothing Then
            GetProductFamily = New DataTable
        Else
            GetProductFamily = dt
        End If

    End Function
    ''' <summary>
    ''' 根据产品名称获取产品列表
    ''' </summary>
    ''' <param name="strProductName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetProductInfoByName(ByVal strProductName As String, ByVal strProductRev As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetProductInfoByName
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT P.*,PB.PRODUCTNAME,WC.WORKCENTERNAME  FROM PRODUCT P ") 'add tianFW 2018年2月5日 增加件号名称
        sb.AppendLine("LEFT JOIN PRODUCTBASE PB ON P.PRODUCTBASEID = PB.PRODUCTBASEID")
        sb.AppendLine("LEFT JOIN WORKCENTER WC ON WC.WORKCENTERID = P.WORKCENTERID") 'add tianFW 2018年1月8日 增加件号工区的查询
        If String.IsNullOrWhiteSpace(strProductRev) Then
            sb.AppendFormat(" WHERE PB.PRODUCTNAME = '{0}'  AND P.PRODUCTID = PB.REVOFRCDID", strProductName)
        ElseIf strProductRev = "%" Then 'add:Wangjh 20190128
            sb.AppendFormat(" WHERE PB.PRODUCTNAME = '{0}'", strProductName)
        Else
            sb.AppendFormat(" WHERE PB.PRODUCTNAME = '{0}'  AND P.PRODUCTREVISION = '{1}'", strProductName, strProductRev)
        End If

        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If dt Is Nothing Then
            GetProductInfoByName = New DataTable
        Else
            GetProductInfoByName = dt
        End If
    End Function

    ''' <summary>
    ''' 根据产品id获取产品列表 CREATE tianFW 2018年1月22日
    ''' </summary>
    ''' <param name="strProductID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetProductInfoByID(ByVal strProductID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetProductInfoByID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT P.*,PB.PRODUCTNAME,wc.workcentername productwcname,pt.producttypename")
        sb.AppendLine("FROM PRODUCT P ")
        sb.AppendLine("LEFT JOIN PRODUCTBASE PB ON P.PRODUCTBASEID = PB.PRODUCTBASEID")
        sb.AppendLine("LEFT JOIN producttype pt ON pt.producttypeid = p.producttypeid") 'add by tianFW 2018年7月20日
        sb.AppendLine("LEFT JOIN Workcenter wc ON wc.workcenterid = p.workcenterid") 'add by tianFW 2018年5月29日 获取件号工区查询
        sb.AppendFormat(" WHERE P.PRODUCTID = '{0}'", strProductID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetProductInfoByID = New DataTable
        Else
            GetProductInfoByID = dt
        End If
    End Function

    ''' <summary>
    ''' 通过工区ID获取班组列表  Create by tianFW
    ''' </summary>
    Public Function GetTeam(ByVal workcenterID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetTeam
        Dim sql As New StringBuilder
        sql.AppendLine("SELECT t.* FROM team t")
        sql.AppendLine("LEFT JOIN workcenter w ON w.workcenterID = t.workcenterID")
        sql.AppendFormat("WHERE w.workcenterID='{0}'", workcenterID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sql.ToString)
        If dt Is Nothing Then
            GetTeam = New DataTable
        Else
            GetTeam = dt
        End If
    End Function
    ''' <summary>
    ''' 获取工区列表
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkCenterByFacoryID(ByVal strFacoryID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkCenterByFacoryID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WC.WORKCENTERNAME, WC.WORKCENTERID,wc.notes,wc.wctype  FROM WORKCENTER WC ")
        sb.AppendFormat("WHERE WC.FACTORYID = '{0}'", strFacoryID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If dt Is Nothing Then
            GetWorkCenterByFacoryID = New DataTable
        Else
            GetWorkCenterByFacoryID = dt
        End If

    End Function

    ''' <summary>
    ''' 获取工区列表 v2.0 create tianFW 2018年3月20日
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkCenterByFacoryID(ByVal strFacoryID As String, ByVal IsNotNormal As Boolean) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkCenterByFacoryID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WC.WORKCENTERNAME, WC.WORKCENTERID,wc.notes,wc.wctype  FROM WORKCENTER WC ")
        sb.AppendFormat("WHERE WC.FACTORYID = '{0}'", strFacoryID)
        If IsNotNormal = False Then
            sb.AppendLine.AppendLine(" AND ((WC.WCTYPE IS NOT NULL AND WC.WCTYPE<>1) OR WC.WCTYPE IS NULL)")
        End If
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If dt Is Nothing Then
            GetWorkCenterByFacoryID = New DataTable
        Else
            GetWorkCenterByFacoryID = dt
        End If

    End Function
    ''' <summary>
    ''' 根据产品获取工艺
    ''' </summary>
    ''' <param name="product"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowByProduct(ByVal product As RevisionedObjectRef) As Camstar.WebClient.WebServicesProxy.InSiteWebServices.RevisionedObjectRef Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowByProduct
        GetWorkFlowByProduct = New RevisionedObjectRef
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WF.WORKFLOWREVISION, WFB1.WORKFLOWNAME,WF.WORKFLOWID  ")
        sb.AppendLine(" FROM PRODUCT P")
        sb.AppendLine("  LEFT JOIN PRODUCTBASE PB ON P.PRODUCTBASEID = PB.PRODUCTBASEID")
        sb.AppendLine("  LEFT JOIN WORKFLOWBASE WFB ON WFB.WORKFLOWBASEID = P.WORKFLOWBASEID")
        sb.AppendLine("  LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = NVL(WFB.REVOFRCDID, P.WORKFLOWID)")
        sb.AppendLine("  LEFT JOIN WORKFLOWBASE WFB1 ON WFB1.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        sb.AppendFormat(" WHERE PB.PRODUCTNAME = '{0}'   AND P.PRODUCTREVISION = '{1}'", product.__name, product.__rev)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            Exit Function
        End If

        If dt.Rows.Count = 0 Then
            Exit Function
        End If
        If IsDBNull(dt.Rows(0)("WORKFLOWID")) Or IsDBNull(dt.Rows(0)("WORKFLOWNAME")) Or IsDBNull(dt.Rows(0)("WORKFLOWREVISION")) Then
            Exit Function
        End If
        GetWorkFlowByProduct.__Id = dt.Rows(0)("WORKFLOWID")
        GetWorkFlowByProduct.__name = dt.Rows(0)("WORKFLOWNAME")
        GetWorkFlowByProduct.__rev = dt.Rows(0)("WORKFLOWREVISION")
        GetWorkFlowByProduct.__useROR = False

    End Function
    ''' <summary>
    ''' 根据产品ID获取工艺列表，包括子工艺，按车间过滤
    ''' update:Wangjh 20180423 修改为第一条为产品默认版本工艺
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowWithSubByProductID(ByVal strProductID As String, ByVal strFactoryID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowWithSubByProductID
        Dim sb As New StringBuilder
        sb.AppendLine("    SELECT WF.WORKFLOWID,WF.WORKFLOWBASEID ,WFB1.WORKFLOWNAME || ':' || WF.WORKFLOWREVISION || '(' || WF.WORKFLOWTYPE || ')' WORKFLOWNAME,T.PRODUCTID, WF.FACTORYID")
        sb.AppendLine("      FROM PRODUCT T")
        sb.AppendLine("      LEFT JOIN WORKFLOWBASE WFB   ON WFB.WORKFLOWBASEID = T.WORKFLOWBASEID")
        sb.AppendLine("      LEFT JOIN WORKFLOW WF    ON WF.WORKFLOWID = NVL(WFB.REVOFRCDID, T.WORKFLOWID)")
        sb.AppendLine("      LEFT JOIN WORKFLOWBASE WFB1     ON WFB1.WORKFLOWBASEID = WF.WORKFLOWBASEID ")
        sb.AppendFormat(" WHERE T.PRODUCTID = '{0}' AND WF.FACTORYID='{1}'", strProductID, strFactoryID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString) '默认的
        Dim revofrcdid As String = "" '默认版本的工艺ID
        If dt.Rows.Count > 0 Then
            revofrcdid = dt.Rows(0)("WORKFLOWID")
        End If
        Dim strSql = "SELECT T.WORKFLOWID,T.WORKFLOWBASEID,  WFB.WORKFLOWNAME || ':' || T.WORKFLOWREVISION || '(' || T.WORKFLOWTYPE || ')' WORKFLOWNAME,T.PRODUCTID, T.FACTORYID" &
                    " FROM WORKFLOW T" &
                    " LEFT JOIN WORKFLOWBASE WFB ON WFB.WORKFLOWBASEID = T.WORKFLOWBASEID "
        strSql += String.Format(" WHERE T.PRODUCTID = '{0}' AND T.FACTORYID='{1}'", strProductID, strFactoryID)
        Dim dt2 As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        For Each row As DataRow In dt2.Rows
            If revofrcdid = row("WORKFLOWID").ToString Then
                Continue For
            End If
            dt.ImportRow(row)
        Next
        dt.AcceptChanges()
        If dt Is Nothing Then
            GetWorkFlowWithSubByProductID = New DataTable
        Else
            GetWorkFlowWithSubByProductID = dt
        End If
    End Function

    ''' <summary>
    ''' 根据工艺ID获取其他版本工艺
    ''' Create：YangSJ
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowOtherRevision(ByVal strWorkflowID As String, ByVal strWorkflowBaseID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowOtherRevision
        Dim sb As New StringBuilder

        sb.AppendLine(" SELECT WF.WORKFLOWID,WF.WORKFLOWBASEID,WFB.WORKFLOWNAME || ':' || WF.WORKFLOWREVISION || '(' || WF.WORKFLOWTYPE || ')' WORKFLOWNAME,WF.FACTORYID,NVL(wf.isuse,'0') isuse ")
        sb.AppendLine(" FROM WORKFLOW WF")
        sb.AppendLine("  LEFT JOIN WORKFLOWBASE WFB  ON WFB.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        sb.AppendFormat(" WHERE WF.WORKFLOWBASEID = '{1}' AND WF.WORKFLOWID <> '{0}'  ", strWorkflowID, strWorkflowBaseID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetWorkFlowOtherRevision = New DataTable
        Else
            GetWorkFlowOtherRevision = dt
        End If
    End Function
    ''' <summary>
    ''' 获取工艺路线所属工艺列表
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowSetps(ByVal workflow As RevisionedObjectRef) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowStepsByWorkFlow
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WT.WORKFLOWSTEPID,WT.WORKFLOWSTEPNAME,WT.SEQUENCE   ")
        sb.AppendLine("FROM WORKFLOWSTEP WT")
        sb.AppendLine("LEFT JOIN WORKFLOW W ON W.WORKFLOWID = WT.WORKFLOWID")
        sb.AppendLine("LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID = W.WORKFLOWBASEID ")
        If String.IsNullOrWhiteSpace(workflow.__rev) Then
            sb.AppendLine(" AND W.WORKFLOWID = WB.REVOFRCDID ")
            sb.AppendFormat(" WHERE WB.WORKFLOWNAME = '{0}' ", workflow.__name)
        Else
            sb.AppendFormat(" WHERE WB.WORKFLOWNAME = '{0}' AND W.WORKFLOWREVISION = '{1}'", workflow.__name, workflow.__rev)
        End If
        sb.AppendLine("ORDER BY WT.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetWorkFlowSetps = New DataTable
        Else
            GetWorkFlowSetps = dt
        End If
    End Function

    ''' <summary>
    ''' 获取工艺路线所属工艺列表
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>2017年12月18日 add tianFW  LEFT JOIN TEAM T ON T.TEAMID = WT.TEAMID查询T.TEAMNAME
    ''' add YangJiang 20180711 ,s.factoryid SpecFactoryid,wf.factoryid WorkFlowFactoryid 
    ''' </remarks>
    Public Function GetWorkFlowSetpsByWorkflowID(ByVal strWorkflowID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowSetpsByWorkflowID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT S.SPECID,S.SPECNO,WT.WORKFLOWSTEPID,WT.WORKFLOWSTEPNAME,WT.SEQUENCE,WT.WORKCENTERID,WT.TEAMID,T.TEAMNAME,SSD.NORMALCYCLETIME ,")
        sb.AppendLine("s.factoryid SpecFactoryid,wf.factoryid WorkFlowFactoryid,DECODE(WT.wipmsglabel,'子工艺','SubWorkflow','Spec') WFSTYPE,st.spectypename")
        sb.AppendLine("FROM WORKFLOWSTEP WT")
        sb.AppendLine("LEFT JOIN STEPSCHEDULINGDETAIL SSD ON SSD.STEPID = WT.WORKFLOWSTEPID")
        sb.AppendLine("LEFT JOIN SPECBASE SB ON SB.SPECBASEID = WT.SPECBASEID")
        sb.AppendLine("LEFT JOIN SPEC S ON S.SPECID = NVL(SB.REVOFRCDID, WT.SPECID)")
        sb.AppendLine("LEFT JOIN TEAM T ON T.TEAMID = WT.TEAMID")
        sb.AppendLine("LEFT JOIN Workflow wf ON wt.workflowid=wf.workflowid") 'add YangJiang 20180711 获取工序所属工艺的所属分厂
        sb.AppendLine("LEFT JOIN spectype st ON st.spectypeid=s.spectypeid") 'add:Wangjh 20190710
        sb.AppendFormat(" WHERE WT.WORKFLOWID= '{0}' AND WT.sequence IS NOT NULL ", strWorkflowID)
        sb.AppendLine("ORDER BY WT.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If dt Is Nothing Then
            GetWorkFlowSetpsByWorkflowID = New DataTable
        Else
            GetWorkFlowSetpsByWorkflowID = dt
        End If
    End Function
    ''' <summary>
    ''' add by longb 2022-05-29 
    ''' 根据【CONTAINERID、WORKFLOWID】获取工艺路线所属工艺信息列表、计划开始/完成时间、状态
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowSetpsByWorkflowIDandContainerID(ByVal para As Dictionary(Of String, String)) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowSetpsByWorkflowIDandContainerID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT S.SPECID,S.SPECNO,WT.WORKFLOWSTEPID,WT.WORKFLOWSTEPNAME,WT.SEQUENCE,WT.WORKCENTERID,WT.TEAMID,T.TEAMNAME,SSD.NORMALCYCLETIME ,")
        sb.AppendLine("s.factoryid SpecFactoryid,wf.factoryid WorkFlowFactoryid,DECODE(WT.wipmsglabel,'子工艺','SubWorkflow','Spec') WFSTYPE,st.spectypename")
        sb.AppendLine(",s.OPDesc,DECODE(s.IsKey,1,'是','否') IsKey,DECODE(wt.IsLastStep,1,'是','否') IsLastStep") 'add by longb 2022-05-29 工序名称、是否关键工序、是否末序
        sb.AppendLine(",nvl(B.PLANNEDSTARTDATE,apd.starttime) PLANNEDSTARTDATE,nvl(B.PLANNEDFINISHDATE,apd.endtime) PLANNEDFINISHDATE,DECODE(NN,NULL,'未派工',DECODE(N,NN,'已派工','未派完')) DispatchStatus") 'add by longb 2022-05-29 工序计划开始/完成时间、状态
        sb.AppendLine("FROM WORKFLOWSTEP WT")
        sb.AppendLine("LEFT JOIN STEPSCHEDULINGDETAIL SSD ON SSD.STEPID = WT.WORKFLOWSTEPID")
        sb.AppendLine("LEFT JOIN SPECBASE SB ON SB.SPECBASEID = WT.SPECBASEID")
        sb.AppendLine("LEFT JOIN SPEC S ON S.SPECID = NVL(SB.REVOFRCDID, WT.SPECID)")
        sb.AppendLine("LEFT JOIN TEAM T ON T.TEAMID = WT.TEAMID")
        sb.AppendLine("LEFT JOIN Workflow wf ON wt.workflowid=wf.workflowid")
        sb.AppendLine("LEFT JOIN spectype st ON st.spectypeid=s.spectypeid")
        sb.AppendLine("LEFT JOIN (--工序下工步个数")
        sb.AppendLine("SELECT COUNT(decode(SO.WORKFLOWSTEPID,NULL,WT.WORKFLOWSTEPID,SO.WORKFLOWSTEPID)) N,WT.WORKFLOWSTEPID FROM WORKFLOWSTEP WT") 'modify by longb 2023-03-28
        sb.AppendLine("LEFT JOIN STEPINFO SO ON so.WORKFLOWSTEPID=WT.WORKFLOWSTEPID")
        sb.AppendFormat(" WHERE WT.WORKFLOWID= '{0}' GROUP BY WT.WORKFLOWSTEPID ", para("WorkflowID"))
        sb.AppendLine(") SO ON SO.WORKFLOWSTEPID = WT.WORKFLOWSTEPID ")
        sb.AppendLine("LEFT JOIN (--批次工序派工表")
        sb.AppendLine("SELECT CSD.WORKFLOWSTEPID,MIN(CSD.PLANNEDSTARTDATE) PLANNEDSTARTDATE,MAX(CSD.PLANNEDFINISHDATE) PLANNEDFINISHDATE,COUNT(CSD.CONTAINERSTEPDISPATCHID) NN")
        sb.AppendLine("FROM CONTAINERSTEPDISPATCH CSD")
        sb.AppendFormat("WHERE CSD.ISUSE=0 AND CSD.CONTAINERID='{0}' GROUP BY CSD.WORKFLOWSTEPID ", para("ContainerID"))
        sb.AppendLine(") B ON B.WORKFLOWSTEPID = WT.WORKFLOWSTEPID ")
        sb.AppendFormat("LEFT JOIN apsplandetail apd ON apd.containerid='{0}' AND apd.workflowstepid=wt.workflowstepid ", para("ContainerID"))
        sb.AppendFormat(" WHERE WT.WORKFLOWID= '{0}' AND WT.sequence IS NOT NULL ", para("WorkflowID"))
        sb.AppendLine("ORDER BY WT.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If dt Is Nothing Then
            GetWorkFlowSetpsByWorkflowIDandContainerID = New DataTable
        Else
            GetWorkFlowSetpsByWorkflowIDandContainerID = dt
        End If
    End Function


    ''' <summary>
    ''' 获取工艺路线所属工艺列表 create tianFW 2017/09/11
    ''' Modify by Yuxj20181217 添加组别显示
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowSetpsDetailByWorkflowID(ByVal para As Dictionary(Of String, String)) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowSetpsDetailByWorkflowID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WT.WORKFLOWSTEPID,WT.WORKFLOWSTEPNAME,WT.SEQUENCE,WF.WORKFLOWID,WB.WORKFLOWNAME,S.SPECREVISION,WT.DESCRIPTION,WF.FACTORYID,WF.WORKFLOWTYPE,")
        sb.AppendLine("WF.WORKFLOWREVISION,S.SPECID,S.SPECNO,SB.SPECNAME,DECODE(WT.wipmsglabel,'子工艺','SubWorkflow','Spec') WFSTYPE,WF.ZGEMPLOYEEID,EM.EMPLOYEENAME,NVL(wf.isuse,'0') isuse ")
        sb.AppendLine(",wt.WORKCENTERCODE WSWORKCENTERID,S.FACTORYID WSFACTORYID,f.FACTORYNAME WSFACTORYNAME,wk.DESCRIPTION WSWORKCENTERNAME,WT.CONTROLCODE,decode(s.ISKEY,1,'是','否') ISKEY,decode(s.LASTCHECK,1,'是','否') LASTCHECK,s.OPERATIONID,o.OPERATIONNAME ")
        If para.ContainsKey("GetFactoryValue") Then 'add 2018年6月13日 tianFW 
            sb.AppendLine(",ua.attributevalue factoryvalue")
        End If

        'Modify by Yuxj20181217 添加组别显示及调整标识 Yuxj20190122添加工区
        If para.ContainsKey("TeamName") Then
            sb.AppendLine(",t.TeamName,t.TeamId,'0' AdjFlag ")
            sb.AppendLine(",wc.workcenterid,wc.workcentername ")
        End If
        If para.ContainsKey("TeamName") Then
            'add by longb 2023-09-22
            If para("TeamName") = "ZS" Then
                sb.AppendLine(",to_char(nvl(WT.PREPARECYCLE,0)) PREPARECYCLE,to_char(nvl(WT.TRANSFERCYCLE,0))TRANSFERCYCLE,to_char(nvl(WT.MAKECYCLE,0)) MAKECYCLE,to_char(nvl(WT.CHANGEOVERCYCLE,0)) CHANGEOVERCYCLE,WT.WORKSTATIONIDS,null WORKSTATIONNAME ")
            End If
        End If


        sb.AppendLine("FROM WORKFLOWSTEP WT")
        sb.AppendLine("LEFT JOIN V_StepRelevantToSonWF sbss on sbss.WORKFLOWSTEPID = WT.WORKFLOWSTEPID")
        sb.AppendLine("LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID= sbss.sonworkflowid")
        sb.AppendLine("LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        sb.AppendLine("LEFT JOIN SPECBASE SB_ ON SB_.SPECBASEID = NVL(WT.SPECBASEID, WT.SUBWORKFLOWBASEID)")
        sb.AppendLine("LEFT JOIN SPEC S ON S.SPECID = NVL(SB_.REVOFRCDID,WT.SPECID)")
        sb.AppendLine("LEFT JOIN SPECBASE SB ON SB.SPECBASEID = S.SPECBASEID")
        sb.AppendLine("LEFT JOIN EMPLOYEE EM ON EM.EMPLOYEEID = WF.ZGEMPLOYEEID")
        sb.AppendLine("LEFT JOIN FACTORY f ON f.FACTORYID =s.FACTORYID") 'add by longb 2025-09-15
        sb.AppendLine("LEFT JOIN ERPWORKCENTERCODE wk ON wk.WORKCENTERCODE =wt.WORKCENTERCODE") 'add by longb 2025-09-15
        sb.AppendLine("LEFT JOIN OPERATION o ON o.OPERATIONID =s.OPERATIONID") 'add by longb 2025-09-15
        If para.ContainsKey("GetFactoryValue") Then 'add 2018年6月13日 tianFW 
            sb.AppendLine("LEFT JOIN Userattribute ua ON ua.parentid = wf.factoryid AND ua.userattributename='空子工艺不允许开卡'")
        End If

        'Modify by Yuxj20181217
        If para.ContainsKey("TeamName") Then
            sb.AppendLine(" LEFT JOIN Team t on t.teamid=wt.teamid ")
            sb.AppendLine(" LEFT JOIN Workcenter wc on wc.workcenterid=wt.workcenterid ")
        End If

        sb.AppendFormat(" WHERE WT.WORKFLOWID= '{0}' And WT.sequence IS NOT NULL ", para("WorkflowID"))
        If para.Keys.Contains("ChildWorkflow") Then
            sb.AppendLine("AND WT.wipmsglabel = '子工艺'")
        End If
        'add YangJiang 20180611
        If para.Keys.Contains("NotChildWorkflow") Then
            sb.AppendLine("AND WT.wipmsglabel is null")
        End If

        sb.AppendLine("ORDER BY WT.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetWorkFlowSetpsDetailByWorkflowID = New DataTable
        Else
            GetWorkFlowSetpsDetailByWorkflowID = dt
        End If
    End Function

    ''' <summary>
    ''' 获取子批次最大序号
    ''' </summary>
    ''' <param name="strPrefix">批次名称</param>
    ''' <param name="numberLength">序号长度</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetNewChildContainerNextIndex(ByVal strPrefix As String, ByVal numberLength As Integer) As Integer Implements IBusiness.uLMSCommonIBusiness.GetNewChildContainerNextIndex
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT C.CONTAINERNAME  FROM CONTAINER C")
        sb.AppendFormat(" WHERE C.CONTAINERNAME LIKE '{0}%' AND C.STATUS<>0 and c.rbcontainertype is null AND c.rbtogetherflag IS NULL and c.ypcontainertype is null", strPrefix) 'add:Wangjh 20220314 增加过滤掉热表和叶片的影响 
        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        GetNewChildContainerNextIndex = 0
        For Each row As DataRow In DT.Rows
            Dim strContianerName As String = row("CONTAINERNAME").ToString().Trim()
            strContianerName = strContianerName.Replace(strPrefix, "")
            If strContianerName.Length < numberLength Then
                Continue For
            End If
            Dim array As String = strContianerName.Substring(0, numberLength)
            Dim intarray As Integer = 0

            If Integer.TryParse(array, intarray) Then
                If intarray > GetNewChildContainerNextIndex Then
                    GetNewChildContainerNextIndex = intarray
                End If
            End If
        Next
    End Function

    ''' <summary>
    ''' 获取已经创建的子批次 createt tianFW 2018年4月2日
    ''' </summary>
    ''' <param name="containerName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetHavedCreateChildContainerInfo(ByVal containerName As String) As DataTable Implements uLMSCommonIBusiness.GetHavedCreateChildContainerInfo
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT C.CONTAINERNAME  FROM CONTAINER C")
        sb.AppendFormat(" WHERE C.CONTAINERNAME LIKE '{0}%' AND C.STATUS<>0", containerName)
        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        Return DT
    End Function

    ''' <summary>
    ''' 获取批次最大序号
    ''' </summary>
    ''' <param name="strPrefix">批次名称</param>
    ''' <param name="numberLength">序号长度</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetNewContainerNextIndex(ByVal strPrefix As String, ByVal numberLength As Integer) As Integer Implements IBusiness.uLMSCommonIBusiness.GetNewContainerNextIndex
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT DISTINCT C.TOGETHERFLAG AS CONTAINERNAME  FROM CONTAINER C")
        sb.AppendFormat(" WHERE C.TOGETHERFLAG LIKE '{0}%' AND C.STATUS<>0 and C.rbcontainertype is null and C.ypcontainertype is null", strPrefix) 'add:Wangjh 20220506 增加过滤掉热表和叶片的影响 
        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        GetNewContainerNextIndex = 0
        For Each row As DataRow In DT.Rows
            Dim strContianerName As String = row("CONTAINERNAME").ToString().Trim()
            strContianerName = strContianerName.Replace(strPrefix, "")
            If strContianerName.Length < numberLength Then
                Continue For
            End If
            Dim array As String = strContianerName.Substring(0, numberLength)
            Dim intarray As Integer = 0

            If Integer.TryParse(array, intarray) Then
                If intarray > GetNewContainerNextIndex Then
                    GetNewContainerNextIndex = intarray
                End If
            End If
        Next
    End Function

    ''' <summary>
    ''' 获取批次指定字段值
    ''' </summary>
    ''' <param name="strContainerName">批次名称</param>
    ''' <param name="strFieldName">字段名称</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetContainerFieldValue(ByVal strContainerName As String, ByVal strFieldName As String) As String Implements IBusiness.uLMSCommonIBusiness.GetContainerFieldValue
        Dim sb As New StringBuilder
        sb.AppendFormat("SELECT C.{0}  FROM CONTAINER C ", strFieldName)
        sb.AppendFormat(" WHERE C.TOGETHERFLAG = '{0}' AND C.STATUS<>0", strContainerName)
        Dim obj As Object = DatabaseHelper.GetSingle(sb.ToString)
        If obj Is Nothing Then
            GetContainerFieldValue = ""
        Else
            GetContainerFieldValue = obj.ToString
        End If

    End Function

    ''' <summary>
    ''' 获取车间配置属性表
    ''' Create：YangSJ
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetFatoryAttributes(ByVal strFactoryID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetFatoryAttributes
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT U.USERATTRIBUTENAME, U.ATTRIBUTEVALUE")
        sb.AppendLine("  FROM USERATTRIBUTE U ")
        sb.AppendFormat("  WHERE U.PARENTID =  '{0}'", strFactoryID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetFatoryAttributes = New DataTable
        Else
            GetFatoryAttributes = dt
        End If
    End Function
    ''' <summary>
    ''' 获取指定工厂配置属性
    ''' Create：YangSJ
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetFatoryAttributes(ByVal strFactoryID As String, ByVal strAttrName As String) As String Implements IBusiness.uLMSCommonIBusiness.GetFatoryAttributes
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT U.ATTRIBUTEVALUE")
        sb.AppendLine("  FROM USERATTRIBUTE U ")
        sb.AppendFormat("  WHERE U.PARENTID =  '{0}'", strFactoryID)
        sb.AppendFormat("  AND U.USERATTRIBUTENAME =  '{0}'", strAttrName)
        Dim objValue As Object = DatabaseHelper.GetSingle(sb.ToString)
        If objValue Is Nothing Then
            GetFatoryAttributes = ""
        Else
            GetFatoryAttributes = objValue.ToString
        End If
    End Function
    ''' <summary>
    ''' 获取企业配置属性
    ''' Create：YangSJ
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEnterpriseAttributes(ByVal strAttrName As String) As String Implements IBusiness.uLMSCommonIBusiness.GetEnterpriseAttributes
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT U.ATTRIBUTEVALUE  FROM  ENTERPRISE E ")
        sb.AppendLine(" LEFT JOIN USERATTRIBUTE U ON E.ENTERPRISEID=U.PARENTID")
        sb.AppendFormat("  WHERE U.USERATTRIBUTENAME =  '{0}'", strAttrName)
        Dim objValue As Object = DatabaseHelper.GetSingle(sb.ToString)
        If objValue Is Nothing Then
            GetEnterpriseAttributes = ""
        Else
            GetEnterpriseAttributes = objValue.ToString
        End If
    End Function

    ''' <summary>
    ''' 获取除当前工序之后的所有工序
    ''' </summary>
    ''' <param name="QueryCondition"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowStepsWithoutSelf(ByVal QueryCondition As System.Collections.Generic.Dictionary(Of String, String)) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowStepsWithoutSelf
        Dim sql As New StringBuilder
        sql.AppendLine("SELECT WS.WORKFLOWSTEPID,WS.WORKFLOWSTEPNAME,WS.SEQUENCE,WS.WORKCENTERID,WS.TEAMID,T.TEAMNAME,WC.WORKCENTERNAME,WS.STEPTYPE,S.SPECNO,")
        sql.AppendLine("WS.SUBWORKFLOWBASEID,WS.SUBWORKFLOWID,ws.wipmsglabel,DECODE(ws.wipmsglabel,'子工艺','是','否') SonWFStep ")
        sql.AppendLine("FROM WORKFLOWSTEP WS")
        If QueryCondition.Keys.Contains("StepDispatch") Then 'add tianFW 2017年11月6日16:25:40
            sql.AppendLine("LEFT JOIN CONTAINERTEAMDISPATCH CTD ON CTD.WORKFLOWSTEPID = WS.WORKFLOWSTEPID")
        End If
        sql.AppendLine("LEFT JOIN TEAM T ON T.TEAMID = WS.TEAMID")
        sql.AppendLine("LEFT JOIN WORKCENTER WC ON WC.WORKCENTERID = WS.WORKCENTERID")
        sql.AppendLine("LEFT JOIN WORKFLOW W ON WS.WORKFLOWID = W.WORKFLOWID")
        sql.AppendLine("LEFT JOIN SPECBASE SB ON SB.SPECBASEID = WS.SPECBASEID")
        sql.AppendLine("LEFT JOIN SPEC S ON S.SPECID = NVL(SB.REVOFRCDID, WS.SPECID)")
        sql.AppendLine("WHERE ws.sequence IS NOT null ") '将1=1 修改为ws.sequence IS NOT null midify by tianFW 2018年12月7日
        If QueryCondition.Keys.Contains("WorkflowID") = True Then
            sql.AppendFormat(" AND W.WorkflowID='{0}'", QueryCondition("WorkflowID"))
        End If
        If QueryCondition.Keys.Contains("Sequence") = True Then
            sql.AppendFormat(" AND WS.Sequence>={0}", QueryCondition("Sequence"))
        End If
        If QueryCondition.Keys.Contains("FactoryID") = True Then
            sql.AppendFormat(" AND S.FACTORYID ='{0}'", QueryCondition("FactoryID"))
        End If
        If QueryCondition.Keys.Contains("StepDispatch") Then 'add tianFW 2017年11月6日 如果是工序工区班组派工则只能看见其班组的工序
            sql.AppendFormat(" AND CTD.ISUSE=0 AND CTD.CONTAINERID ='{0}' AND CTD.TEAMID ='{1}'", QueryCondition("ContainerID"), QueryCondition("TeamID"))
        End If
        If QueryCondition.Keys.Contains("ShipID") = True Then
            sql.AppendFormat(" and ws.workflowstepid in (select workflowstepid from containershiprecordstep csds where csds.containershiprecordid='{0}') ", QueryCondition("ShipID"))
        End If
        sql.AppendLine(" Order by WS.Sequence ")
        Dim strsql As String = sql.ToString
        Dim result As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql)

        Return result
    End Function

    ''' <summary>
    ''' 根据工区类型获取信息 Yuxj20190516
    ''' </summary>
    ''' <param name="QueryCondition"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkCenterWithWCTYPE(ByVal QueryCondition As Dictionary(Of String, String)) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkCenterWithWCTYPE
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT wc.workcentername,wc.workcenterid  FROM workcenter wc ")
        strsql.AppendLine("LEFT JOIN factory fa ON wc.factoryid=fa.factoryid ")
        strsql.AppendLine("WHERE wc.wctype=1 ")
        strsql.AppendFormat("and fa.FactoryID='{0}'", QueryCondition("FactoryID"))
        Dim result As New DataTable
        result = DatabaseHelper.Query_ReturnDatTable(strsql.ToString)
        Return result
    End Function


    ''' <summary>
    ''' 获取当前用户所属车间下的其他工区
    ''' </summary>
    ''' <param name="QueryCondition"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkCenterWithoutSelf(ByVal QueryCondition As Dictionary(Of String, String)) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkCenterWithoutSelf
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT wc.workcentername,wc.workcenterid  FROM workcenter wc")
        strsql.AppendLine("LEFT JOIN factory fa ON wc.factoryid=fa.factoryid")
        strsql.AppendLine("WHERE 1=1")
        If QueryCondition.Keys.Contains("currentWorkCenter") = True Then
            strsql.AppendFormat("and wc.workcentername<>'{0}'", QueryCondition("currentWorkCenter"))
        End If
        If QueryCondition.Keys.Contains("currentFactoryName") = True Then
            strsql.AppendFormat("and fa.factoryname='{0}'", QueryCondition("currentFactoryName"))
        End If
        If QueryCondition.ContainsKey("FilterNoUse") Then 'add:Wangjh 20180320 筛选无用的工区
            strsql.AppendLine(" AND  ((WC.WCTYPE IS NOT NULL AND WC.WCTYPE<>1) OR WC.WCTYPE IS NULL)")
        End If
        Dim result As New DataTable
        result = DatabaseHelper.Query_ReturnDatTable(strsql.ToString)

        Return result
    End Function

    ''' <summary>
    ''' 获取产品名版本工序列表
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowStepsByProduct(ByVal strProductName As String, ByVal strProductRev As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowStepsByProduct
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WFS.WORKFLOWSTEPID, WFS.WORKFLOWSTEPNAME, WFS.SEQUENCE,WFS.WORKFLOWID")
        sb.AppendLine("  FROM PRODUCT P")
        sb.AppendLine("  LEFT JOIN PRODUCTBASE PB ON P.PRODUCTBASEID=PB.PRODUCTBASEID")
        sb.AppendLine("  LEFT JOIN WORKFLOWBASE WFB  ON P.WORKFLOWBASEID = WFB.WORKFLOWBASEID")
        sb.AppendLine("  LEFT JOIN WORKFLOW WF  ON P.WORKFLOWID = NVL(WFB.REVOFRCDID, WF.WORKFLOWID)")
        sb.AppendLine(" LEFT JOIN WORKFLOWSTEP WFS  ON WF.WORKFLOWID = WFS.WORKFLOWID")
        sb.AppendFormat(" WHERE PB.PRODUCTNAME='{0}' AND P.PRODUCTREVISION='{1}'", strProductName, strProductRev)
        sb.AppendLine(" ORDER BY WFS.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetWorkFlowStepsByProduct = New DataTable
        Else
            GetWorkFlowStepsByProduct = dt
        End If
    End Function

    ''' <summary>
    ''' 根据TeamId获取人员信息
    ''' </summary>
    ''' <param name="stringTeamid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEmployeeInfoByTeamId(ByVal stringTeamid As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetEmployeeInfoByTeamId
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT em.*,T.TEAMID,T.TEAMNAME FROM employee em")
        strsql.AppendLine("LEFT JOIN teamemployee tem ON tem.employeeid = em.employeeid")
        strsql.AppendLine("LEFT JOIN team t ON t.teamid = tem.teamid ")
        strsql.AppendFormat("WHERE t.teamid ='{0}'", stringTeamid)
        strsql.AppendLine(" ORDER BY EM.FULLNAME") 'Add tianFW 按名字首字母排序 2018年3月20日 
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql.ToString)
        If dt Is Nothing Then
            GetEmployeeInfoByTeamId = New DataTable
        Else
            GetEmployeeInfoByTeamId = dt
        End If
    End Function
    ''' <summary>
    ''' 根据employeeid获取资源信息
    ''' </summary>
    ''' <param name="employeeids"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetResourceDefByemployeeid(ByVal employeeids As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetResourceDefByemployeeid
        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT re.description||'('||re.resourcename||')' RESNAME,re.* FROM resourcedef re")
        strSql.AppendLine("LEFT JOIN employeeresourcelist emreli ON emreli.resourcelistid = re.resourceid")
        strSql.AppendLine("LEFT JOIN employee em ON em.employeeid = emreli.employeeid ")
        strSql.AppendFormat("WHERE {0}", employeeids)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql.ToString)
        If dt Is Nothing Then
            GetResourceDefByemployeeid = New DataTable
        Else
            GetResourceDefByemployeeid = dt
        End If
    End Function

    ''' <summary>
    ''' 根据Factoryid获取资源信息
    ''' </summary>
    ''' <param name="Factoryid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetResourceDefByFactoryid(ByVal Factoryid As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetResourceDefByFactoryid
        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT RE.DESCRIPTION || '(' || RE.RESOURCENAME || ')' RESNAME, RE.* FROM RESOURCEDEF RE")
        strSql.AppendFormat("WHERE RE.FACTORYID='{0}'", Factoryid)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql.ToString)
        If dt Is Nothing Then
            GetResourceDefByFactoryid = New DataTable
        Else
            GetResourceDefByFactoryid = dt
        End If
    End Function

    ''' <summary>
    ''' 根据组名获取报废原因
    ''' Create:YangSJ
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetLossReasonByGroupName(ByVal strGroupName As String) As DataTable Implements uLMSCommonIBusiness.GetLossReasonByGroupName
        Dim sb = New StringBuilder
        sb.AppendLine("SELECT LR.LOSSREASONID, LR.LOSSREASONNAME, LR.DESCRIPTION,LR.LOSSREASONNAME||LR.DESCRIPTION FECOD ") 'add YangJiang LR.LOSSREASONNAME||LR.DESCRIPTION FECOD
        sb.AppendLine("FROM LOSSREASONGROUP L")
        sb.AppendLine(" LEFT JOIN NAMEDOBJECTGROUPENTRIES N    ON N.NAMEDOBJECTGROUPID = L.LOSSREASONGROUPID")
        sb.AppendLine(" LEFT JOIN LOSSREASON LR ON LR.LOSSREASONID = N.ENTRIESID")
        sb.AppendFormat("WHERE L.LOSSREASONGROUPNAME ='{0}' ", strGroupName)
        sb.AppendLine("  ORDER BY N.SEQUENCE ")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetLossReasonByGroupName = New DataTable
        Else
            GetLossReasonByGroupName = dt
        End If
    End Function

    ''' <summary>
    ''' 获取报废原因组
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetLossReasonGroupData() As DataTable Implements IBusiness.uLMSCommonIBusiness.GetLossReasonGroupData
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT LRG.LOSSREASONGROUPNAME, LRG.LOSSREASONGROUPID,") 'add Yangjiang , LRG.LOSSREASONGROUPNAME||LRG.DESCRIPTION FEGRP 
        strsql.AppendLine("LRG.LOSSREASONGROUPNAME||LRG.DESCRIPTION FEGRP,LRG.LOSSREASONGROUPNAME||'('||LRG.DESCRIPTION||')' LOSSREASONGROUPFULLNAME")
        strsql.AppendLine("FROM LOSSREASONGROUP LRG WHERE LRG.LOSSREASONGROUPNAME LIKE '%LY%'")
        Dim result As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql.ToString)
        Return result
    End Function

    ''' <summary>
    ''' 根据组ID获取报废原因
    ''' Create:YangSJ
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetLossReasonByGroupID(ByVal strGroupID As String) As DataTable Implements uLMSCommonIBusiness.GetLossReasonByGroupID

        Dim sb = New StringBuilder
        sb.AppendLine("SELECT LR.LOSSREASONID, LR.LOSSREASONNAME, LR.DESCRIPTION, LR.LOSSREASONNAME||'('|| LR.DESCRIPTION||')' LOSSREASONFULLNAME")
        sb.AppendLine("  FROM LOSSREASON LR")
        sb.AppendLine("  LEFT JOIN NAMEDOBJECTGROUPENTRIES N    ON LR.LOSSREASONID = N.ENTRIESID ")
        sb.AppendFormat(" WHERE N.NAMEDOBJECTGROUPID ='{0}' ", strGroupID)
        sb.AppendLine("  ORDER BY N.SEQUENCE ")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetLossReasonByGroupID = New DataTable
        Else
            GetLossReasonByGroupID = dt
        End If
    End Function

    ''' <summary>
    ''' 获取NDO原因代码根据原因代码组
    ''' add:Wangjh 20190328
    ''' </summary>
    ''' <param name="reasonTable"></param>
    ''' <param name="groupName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetNDOReasionByGroupName(ByVal reasonTable As String, ByVal groupName As String) As DataTable Implements uLMSCommonIBusiness.GetNDOReasionByGroupName
        Dim strSql As String = String.Format(<string>
                                  SELECT lr.*  FROM {0}group t
                                LEFT JOIN NAMEDOBJECTGROUPENTRIES N    ON N.NAMEDOBJECTGROUPID = t.{0}groupid
                                LEFT JOIN {0} lr ON lr.{0}id=N.ENTRIESID
                                WHERE t.{0}groupname='{1}'
                              </string>.Value, reasonTable, groupName)
        Return DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 获取当前用户所属企业的其他分厂
    ''' create:Wangjh
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetFactoryWithoutSelf(ByVal factoryID As String) As DataTable Implements uLMSCommonIBusiness.GetFactoryWithoutSelf
        Dim strSql As String = "SELECT FA.FACTORYNAME, FA.FACTORYID FROM FACTORY FA "
        strSql += String.Format(" WHERE FA.FACTORYID <> '{0}' AND FA.ENTERPRISEID IS NOT NULL", factoryID)
        Dim result As New DataTable
        result = DatabaseHelper.Query_ReturnDatTable(strSql)
        Return result
    End Function
    ''' <summary>
    ''' 获取不属于当前企业的所有分厂
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetFactoryWithoutEnterprise() As DataTable Implements uLMSCommonIBusiness.GetFactoryWithoutEnterprise
        Dim strSql As String = "SELECT * FROM FACTORY FA WHERE FA.ENTERPRISEID IS  NULL	"
        GetFactoryWithoutEnterprise = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 根据父ContainerID查询ContainerID和ContainerName
    ''' create tianFW
    ''' </summary>
    ''' <param name="containerID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetContainerInfoByPerContianerID(ByVal containerID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetContainerInfoByPerContianerID
        Dim sqlstr As New StringBuilder
        'sqlstr.AppendFormat(" SELECT C.CONTAINERID, C.CONTAINERNAME,C.PARENTCONTAINERID FROM CONTAINER C WHERE C.PARENTCONTAINERID = '{0}'", containerID)
        'sqlstr.AppendLine("AND C.STATUS =1")
        sqlstr.AppendLine(" SELECT C.CONTAINERID, C.CONTAINERNAME,spr.inputseq FROM container c ")
        sqlstr.AppendLine(" LEFT JOIN stepcheckpointresult spr  ON c.containerid = spr.containerid")
        sqlstr.AppendLine(" WHERE C.PARENTCONTAINERID = '" + containerID + "' AND C.STATUS =1 ORDER BY C.CONTAINERID")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sqlstr.ToString)
        Return dt
    End Function

    Function GetContainerInfoByPerContianerID2(ByVal containerID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetContainerInfoByPerContianerID2
        Dim sqlstr As New StringBuilder
        sqlstr.AppendFormat(" SELECT C.CONTAINERID, C.CONTAINERNAME,C.PARENTCONTAINERID FROM CONTAINER C WHERE C.PARENTCONTAINERID = '{0}'", containerID)
        sqlstr.AppendLine("AND C.STATUS =1 ORDER BY C.CONTAINERID")
        'sqlstr.AppendLine(" SELECT C.CONTAINERID, C.CONTAINERNAME,spr.checkpointresultnote,spr.inputseq FROM container c ")
        'sqlstr.AppendLine(" LEFT JOIN stepcheckpointresult spr  ON c.containerid = spr.containerid")
        'sqlstr.AppendLine(" WHERE C.PARENTCONTAINERID = '" + containerID + "' AND C.STATUS =1")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sqlstr.ToString)
        Return dt
    End Function

    ''' <summary>
    ''' 创建不合格品类别表 Create tianFW
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function AddUnqualifiedCategory() As DataTable Implements IBusiness.uLMSCommonIBusiness.AddUnqualifiedCategory
        Dim dt As New DataTable
        dt.Columns.Add("UnqualifiedCategoryName")
        dt.Columns.Add("UnqualifiedCategoryValue")
        Dim row1 As DataRow = dt.NewRow
        Dim row2 As DataRow = dt.NewRow
        Dim row3 As DataRow = dt.NewRow
        Dim row4 As DataRow = dt.NewRow
        row1("UnqualifiedCategoryName") = "0类"
        row1("UnqualifiedCategoryValue") = "0"
        row2("UnqualifiedCategoryName") = "Ⅰ类"
        row2("UnqualifiedCategoryValue") = "Ⅰ"
        row3("UnqualifiedCategoryName") = "Ⅱ类"
        row3("UnqualifiedCategoryValue") = "Ⅱ"
        row4("UnqualifiedCategoryName") = "Ⅲ类"
        row4("UnqualifiedCategoryValue") = "Ⅲ"
        dt.Rows.Add(row1)
        dt.Rows.Add(row2)
        dt.Rows.Add(row3)
        dt.Rows.Add(row4)
        Return dt
    End Function

    ''' <summary>
    ''' 添加审理单位表 create tianFW
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function AddTrialUnit() As DataTable Implements IBusiness.uLMSCommonIBusiness.AddTrialUnit
        Dim dt As New DataTable
        Dim row1 As DataRow = dt.NewRow
        Dim row2 As DataRow = dt.NewRow
        Dim row3 As DataRow = dt.NewRow
        Dim row4 As DataRow = dt.NewRow
        Dim row5 As DataRow = dt.NewRow
        Dim row6 As DataRow = dt.NewRow
        Dim row7 As DataRow = dt.NewRow
        dt.Columns.Add("TrialUnitName")
        dt.Columns.Add("TrialUnitValue")
        row1("TrialUnitName") = "盘轴厂"
        row2("TrialUnitName") = "机匣厂"
        row3("TrialUnitName") = "热表厂"
        row4("TrialUnitName") = "装配试车厂"
        row5("TrialUnitName") = "钣焊厂"
        row6("TrialUnitName") = "叶片厂"
        row7("TrialUnitName") = "结构件厂"
        row1("TrialUnitValue") = "600"
        row2("TrialUnitValue") = "601"
        row3("TrialUnitValue") = "602"
        row4("TrialUnitValue") = "603"
        row5("TrialUnitValue") = "607"
        row6("TrialUnitValue") = "608"
        row7("TrialUnitValue") = "609"
        dt.Rows.Add(row1)
        dt.Rows.Add(row2)
        dt.Rows.Add(row3)
        dt.Rows.Add(row4)
        dt.Rows.Add(row5)
        dt.Rows.Add(row6)
        dt.Rows.Add(row7)
        Return dt
    End Function

    ''' <summary>
    ''' 添加零件类别 create tianFW
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function AddPartCategory() As DataTable Implements IBusiness.uLMSCommonIBusiness.AddPartCategory
        Dim dt As New DataTable
        Dim row1 As DataRow = dt.NewRow
        Dim row2 As DataRow = dt.NewRow
        Dim row3 As DataRow = dt.NewRow
        Dim row4 As DataRow = dt.NewRow
        dt.Columns.Add("PartCategoryName")
        dt.Columns.Add("PartCategoryValue")
        row1("PartCategoryName") = "关键件"
        row2("PartCategoryName") = "重要件"
        row3("PartCategoryName") = "一般件"
        row4("PartCategoryName") = "试验件"
        row1("PartCategoryValue") = "01"
        row2("PartCategoryValue") = "02"
        row3("PartCategoryValue") = "03"
        row4("PartCategoryValue") = "04"
        dt.Rows.Add(row1)
        dt.Rows.Add(row2)
        dt.Rows.Add(row3)
        dt.Rows.Add(row4)
        Return dt
    End Function

    ''' <summary>
    ''' 添加责任单位表 create tianFW
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function AddDutyUnit() As DataTable Implements IBusiness.uLMSCommonIBusiness.AddDutyUnit
        Dim dt As New DataTable
        Dim row1 As DataRow = dt.NewRow
        Dim row2 As DataRow = dt.NewRow
        Dim row3 As DataRow = dt.NewRow
        Dim row4 As DataRow = dt.NewRow
        Dim row5 As DataRow = dt.NewRow
        Dim row6 As DataRow = dt.NewRow
        Dim row7 As DataRow = dt.NewRow
        Dim row8 As DataRow = dt.NewRow
        Dim row9 As DataRow = dt.NewRow
        Dim row10 As DataRow = dt.NewRow
        Dim row11 As DataRow = dt.NewRow
        dt.Columns.Add("DutyUnitName")
        dt.Columns.Add("DutyUnitValue")
        row1("DutyUnitName") = "外委厂家1"
        row2("DutyUnitName") = "外委厂家2"
        row3("DutyUnitName") = "盘轴厂"
        row4("DutyUnitName") = "机匣厂"
        row5("DutyUnitName") = "热表厂"
        row6("DutyUnitName") = "装配试车厂"
        row7("DutyUnitName") = "钣焊厂"
        row8("DutyUnitName") = "叶片厂"
        row9("DutyUnitName") = "结构件厂"
        row10("DutyUnitName") = "其他"
        row1("DutyUnitValue") = "901"
        row2("DutyUnitValue") = "902"
        row3("DutyUnitValue") = "600"
        row4("DutyUnitValue") = "601"
        row5("DutyUnitValue") = "602"
        row6("DutyUnitValue") = "603"
        row7("DutyUnitValue") = "607"
        row8("DutyUnitValue") = "608"
        row9("DutyUnitValue") = "609"
        row10("DutyUnitValue") = "903"
        dt.Rows.Add(row1)
        dt.Rows.Add(row2)
        dt.Rows.Add(row3)
        dt.Rows.Add(row4)
        dt.Rows.Add(row5)
        dt.Rows.Add(row6)
        dt.Rows.Add(row7)
        dt.Rows.Add(row8)
        dt.Rows.Add(row9)
        Return dt
    End Function

    ''' <summary>
    ''' 添加编码-代码表 create tianFW
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function AddEncodeCode() As DataTable Implements IBusiness.uLMSCommonIBusiness.AddEncodeCode
        Dim dt As New DataTable
        Dim row1 As DataRow = dt.NewRow
        Dim row2 As DataRow = dt.NewRow
        Dim row3 As DataRow = dt.NewRow
        Dim row4 As DataRow = dt.NewRow
        Dim row5 As DataRow = dt.NewRow
        Dim row6 As DataRow = dt.NewRow
        Dim row7 As DataRow = dt.NewRow
        dt.Columns.Add("EncodeCodeName")
        dt.Columns.Add("EncodeCodeValue")
        row1("EncodeCodeName") = "600-盘轴厂"
        row2("EncodeCodeName") = "601-机匣厂"
        row3("EncodeCodeName") = "602-热表厂"
        row4("EncodeCodeName") = "603-装配试车厂"
        row5("EncodeCodeName") = "607-钣焊厂"
        row6("EncodeCodeName") = "608-叶片厂"
        row7("EncodeCodeName") = "609-结构件厂"
        row1("EncodeCodeValue") = "D010"
        row2("EncodeCodeValue") = "D020"
        row3("EncodeCodeValue") = "D030"
        row4("EncodeCodeValue") = "D040"
        row5("EncodeCodeValue") = "D050"
        row6("EncodeCodeValue") = "D060"
        row7("EncodeCodeValue") = "D070"
        dt.Rows.Add(row1)
        dt.Rows.Add(row2)
        dt.Rows.Add(row3)
        dt.Rows.Add(row4)
        dt.Rows.Add(row5)
        dt.Rows.Add(row6)
        dt.Rows.Add(row7)
        Return dt
    End Function

    ''' <summary>
    ''' 根据原因组ID和原因ID获取缺陷序号和短文本描述
    ''' creat：Wangjh
    ''' </summary>
    ''' <param name="strGroupID"></param>
    ''' <param name="strLossReasonID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetLossSequenceAndDesc(ByVal strGroupID As String, ByVal strLossReasonID As String) As DataTable Implements uLMSCommonIBusiness.GetLossSequenceAndDesc
        Dim strSql As String = String.Format("SELECT NOGT.SEQUENCE,LR.DESCRIPTION,LRG.LOSSREASONGROUPNAME,LR.LOSSREASONNAME FROM LOSSREASONGROUP LRG" &
                                             " LEFT JOIN NAMEDOBJECTGROUPENTRIES NOGT ON NOGT.NAMEDOBJECTGROUPID = LRG.LOSSREASONGROUPID" &
                                             " LEFT JOIN LOSSREASON LR ON NOGT.ENTRIESID = LR.LOSSREASONID" &
                                             " WHERE LR.LOSSREASONID = '{0}' AND NOGT.NAMEDOBJECTGROUPID = '{1}'" &
                                             " ORDER BY NOGT.SEQUENCE", strLossReasonID, strGroupID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        If dt Is Nothing Then
            GetLossSequenceAndDesc = New DataTable
        Else
            GetLossSequenceAndDesc = dt
        End If
    End Function
    ''' <summary>
    ''' 判断当前工序承制分厂是否是本分厂
    ''' create:Wangjh
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function IsSpecOfCurrentFactory(ByVal workFlowStepID As String, ByVal FactoryID As String) As Boolean Implements uLMSCommonIBusiness.IsSpecOfCurrentFactory
        Dim strSql As String = "SELECT S.* FROM SPEC S" &
                "LEFT JOIN WORKFLOWSTEP WS ON (WS.SPECBASEID = S.SPECBASEID AND WS.SPECID = '0000000000000000')" &
                " OR (WS.SPECID = S.SPECID AND WS.SPECBASEID = '0000000000000000')"
        strSql += String.Format(" WHERE WS.WORKFLOWSTEPID = '{0}' AND S.FACTORYID = '{1}'", workFlowStepID, FactoryID)

        Dim result As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)

        If result.Rows.Count > 0 Then
            IsSpecOfCurrentFactory = True
            Exit Function
        End If
        IsSpecOfCurrentFactory = False
    End Function

    ''' <summary>
    ''' 查询当前带子序号的批次当前序已派工的子序号
    ''' </summary>
    ''' <param name="contaienrid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetContainerStepWorkReportChildInfo(ByVal contaienrid As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetContainerStepWorkReportChildInfo
        Dim strsql As String = String.Format("SELECT Distinct C.CONTAINERNAME, CSWC.CHILDCONTAINERID FROM CONTAINERSTEPWORKREPORTCHILD CSWC" &
                " LEFT JOIN CONTAINERSTEPWORKREPORT CSW ON CSW.CONTAINERSTEPWORKREPORTID = CSWC.CONTAINERSTEPWORKREPORTID  AND CSW.ISUSE = 0" &
                " LEFT JOIN CONTAINERCURRENTINFO C ON C.CONTAINERID = CSW.CONTAINERID AND C.WORKFLOWSTEPID = CSW.WORKFLOWSTEPID" &
                " WHERE C.CONTAINERID = '{0}'", contaienrid)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql)
        Return dt
    End Function

    ''' <summary>
    ''' 根据工序ID查询workflowName和workflowVision create tianFW
    ''' </summary>
    ''' <param name="workflowstepid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowNameAndWorkflowVision(ByVal workflowstepid As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowNameAndWorkflowVision
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT WFB.WORKFLOWNAME, WF.WORKFLOWREVISION FROM WORKFLOWSTEP WS")
        strsql.AppendLine("LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = WS.WORKFLOWID")
        strsql.AppendLine("LEFT JOIN WORKFLOWBASE WFB ON WFB.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        strsql.AppendFormat(" WHERE WS.WORKFLOWSTEPID = '{0}'", workflowstepid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString)
    End Function

    ''' <summary>
    ''' 根据工序ID获取ControlCode create tianFW
    ''' </summary>
    ''' <param name="WorkflowStepID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetControlCodeByWorkflowStepID(ByVal WorkflowStepID As String) As String Implements IBusiness.uLMSCommonIBusiness.GetControlCodeByWorkflowStepID
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT NVL(WS.CONTROLCODE,S.CONTROLCODE) CONTROLCODE FROM WORKFLOWSTEP WS ")
        strsql.AppendLine("LEFT JOIN SPECBASE SB ON SB.SPECBASEID = WS.SPECBASEID")
        strsql.AppendLine("LEFT JOIN SPEC S ON S.SPECID = NVL(SB.REVOFRCDID, WS.SPECID) ")
        strsql.AppendLine("LEFT JOIN WORKFLOWBASE WB_ ON WB_.WORKFLOWBASEID = WS.SUBWORKFLOWBASEID")
        strsql.AppendLine("LEFT JOIN WORKFLOW CWF ON CWF.WORKFLOWID=NVL(WB_.REVOFRCDID,WS.SUBWORKFLOWID)")
        strsql.AppendLine("LEFT JOIN Workflow WF ON WF.WORKFLOWID = WS.WORKFLOWID")
        strsql.AppendFormat("WHERE WS.WORKFLOWSTEPID = '{0}'", WorkflowStepID)
        strsql.AppendLine("AND S.FACTORYID = WF.FACTORYID AND ((CWF.WORKFLOWID IS NOT NULL AND CWF.FACTORYID = S.FACTORYID) OR (CWF.WORKFLOWID IS NULL))")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
        If dt.Rows.Count = 0 Then
            Return ""
        End If
        If Not String.IsNullOrWhiteSpace(dt.Rows(0)("CONTROLCODE").ToString) Then
            Return dt.Rows(0)("CONTROLCODE")
        Else
            Return ""
        End If
    End Function

    ''' <summary>
    ''' 获取是固定外委、固定转工、检验工序的所有工序 create tianFW
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowStepsWithSpceControlCodeAndCheckStep(ByVal WorkflowID As String, ByVal factroyID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowStepsWithSpceControlCodeAndCheckStep
        Dim sql As New StringBuilder
        sql.AppendLine("SELECT WS.WORKFLOWSTEPID,WS.WORKFLOWSTEPNAME,WS.SEQUENCE,S.CONTROLCODE,S.LASTCHECK,S.FACTORYID")
        sql.AppendLine("FROM WORKFLOWSTEP WS")
        sql.AppendLine("LEFT JOIN WORKFLOW W ON WS.WORKFLOWID = W.WORKFLOWID")
        sql.AppendLine("LEFT JOIN SPECBASE SB ON SB.SPECBASEID = WS.SPECBASEID")
        sql.AppendLine("LEFT JOIN SPEC S ON S.SPECID = NVL(SB.REVOFRCDID, WS.SPECID)")
        sql.AppendFormat(" WHERE W.WorkflowID='{0}' AND (nvl(ws.CONTROLCODE,S.CONTROLCODE)='LY05' OR S.FACTORYID <> '{1}'", WorkflowID, factroyID)
        If GetFatoryAttributes(factroyID, "检验序自动报工") = "是" Then
            sql.AppendLine("OR S.LASTCHECK ='1'")
        End If
        sql.AppendLine(")")
        Dim strsql As String = sql.ToString
        Dim result As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql)

        Return result
    End Function

    ''' <summary>
    ''' 根据ContainerName获取批次数量、ID create tianfw
    ''' </summary>
    ''' <param name="containername"></param>
    ''' <returns></returns>
    ''' <remarks></remarks> 
    Public Function GetContainerInfobyContainerName(ByVal containername As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetContainerInfobyContainerName
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT T.TEAMNAME,C.TEAMID,C.ISSELFMFG,C.MFGBATCH,C.WORKCENTERID,C.QTY,C.CONTAINERID,C.ORIGINALFACTORYID FACTORYID,U.ATTRIBUTEVALUE TECHNIQUE ")
        strsql.AppendLine("FROM CONTAINER C")
        strsql.AppendLine("LEFT JOIN TEAM T ON T.TEAMID = C.TEAMID")
        strsql.AppendLine("LEFT JOIN USERATTRIBUTE U ON U.PARENTID = C.CONTAINERID AND U.USERATTRIBUTENAME = 'CheckTechnique'")
        strsql.AppendFormat(" WHERE C.CONTAINERNAME='{0}' AND C.STATUS=1", containername)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function
    ''' <summary>
    ''' 获取当前登录用户信息
    ''' create:Wangjh
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetCurrentUserInfo(ByVal strEmployeeName As String, ByVal strSessionID As String) As uMESProcessResult Implements uLMSCommonIBusiness.GetCurrentUserInfo

        'add  e.shiftid 增加用户shiftid,r.resourcename,e.paycard查询 2018年5月22日
        Dim strSelect As String = <string>
                                       SELECT e.employeename,e.employeeid,e.fullname,f.factoryname,f.factoryid,f.description AS FactoryEName,wc.workcentername,
                                        wc.workcenterID,o.operationname,e.cardnum,eroles.rolenames,te.teamid,te.teamname,e.password,
                                        nvl(e.shiftid,te.shiftid) shiftid,r.resourcename,e.paycard
                                        FROM employee e 
                                  </string>
        Dim sb As New StringBuilder
        sb.AppendLine(strSelect)
        sb.AppendLine("   LEFT JOIN sessionvalues sv ON sv.sessionvaluesid = e.sessionvaluesid ")
        sb.AppendLine(" LEFT JOIN factory f ON f.factoryid = sv.factoryid ")
        sb.AppendLine("  LEFT JOIN workcenter wc ON wc.workcenterid = sv.workcenterid ")
        sb.AppendLine(" LEFT JOIN operation o ON o.operationid = sv.operationid ")
        sb.AppendLine("LEFT JOIN resourcedef r ON r.resourceid = e.resourceid")
        sb.AppendLine(" LEFT JOIN ( SELECT e.employeeid,wm_concat(r.rolename) AS rolenames  FROM employeerole er  LEFT JOIN employee e ON e.employeeid = er.employeeid  LEFT JOIN roledef r ON r.roleid = er.roleid  GROUP BY e.employeeid " &
                            "  ) eroles ON eroles.employeeid = e.employeeid ")

        sb.AppendLine("  LEFT JOIN (SELECT  t.teamname,t.teamid,te.employeeid,t.shiftid FROM teamemployee te LEFT JOIN team t  ON t.teamid = te.teamid  ) te  " &
                           "   ON te.employeeid = e.employeeid AND ROWNUM = 1 ")
        sb.AppendFormat("  WHERE LOWER(e.employeename) = LOWER('{0}')", strEmployeeName)
        Dim result As New uMESProcessResult
        Try
            Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
            result.Result = True
            result.DBTable = DT
            If Not String.IsNullOrWhiteSpace(strSessionID) Then
                Dim strQuery As String = String.Format(" DELETE FROM ACTIVEUSERSESSION WHERE ACTIVEUSERSESSIONID='{0}'", strSessionID)
                DatabaseHelper.ExecuteSql(strQuery)
            End If

        Catch ex As Exception
            result.Result = False
            result.Message = ex.Message
        End Try

        Return result
    End Function

    ''' <summary>
    ''' 获取自然数表级  create tianFW
    ''' </summary>
    ''' <param name="strSql"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetNaturalNumberDatatable(ByVal strSql As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetNaturalNumberDatatable
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        dt.Columns.Add("PRIORITYCODENAME")
        For Each dr As DataRow In dt.Rows
            dr("PRIORITYCODENAME") = dr("PRIORITYCODE").ToString + "级"
        Next
        dt.AcceptChanges()
        Return dt
    End Function

    ''' <summary>
    ''' 获取员工的角色信息
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetEmployeeRoles(ByVal para As Dictionary(Of String, String)) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetEmployeeRoles
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT EM.EMPLOYEEID CHECKERID, EM.EMPLOYEENAME, EM.FULLNAME, RD.ROLENAME,EM.CARDNUM FROM EMPLOYEE EM")
        strsql.AppendLine("LEFT JOIN EMPLOYEEROLE EMR ON EMR.EMPLOYEEID = EM.EMPLOYEEID")
        strsql.AppendLine("LEFT JOIN ROLEDEF RD ON RD.ROLEID = EMR.ROLEID")
        strsql.AppendLine("LEFT JOIN SESSIONVALUES SE ON SE.EMPLOYEEID = EM.EMPLOYEEID")
        'modify tianFW 2017/09/13
        If (para.Keys.Contains("Other") Or para.Keys.Contains("NoTeam")) And para.Keys.Contains("FactoryID") And para.Keys.Contains("NoGroup") Then
            strsql.AppendLine("LEFT JOIN TEAMEMPLOYEE TEM ON TEM.EMPLOYEEID = EM.EMPLOYEEID")
            strsql.AppendLine("LEFT JOIN SHIFT S ON EM.SHIFTID = S.SHIFTID")

        ElseIf (para.Keys.Contains("Other") Or para.Keys.Contains("NoTeam")) And para.Keys.Contains("FactoryID") Then
            strsql.AppendLine("LEFT JOIN TEAMEMPLOYEE TEM ON TEM.EMPLOYEEID = EM.EMPLOYEEID")

        ElseIf para.Keys.Contains("noShift") And para.Keys.Contains("WorkCenterID") Then 'modify YangJiang 2018/03/20
            strsql.AppendLine("LEFT JOIN SHIFT S ON EM.SHIFTID = S.SHIFTID")
        End If
        strsql.AppendFormat("WHERE SE.FACTORYID = '{0}'", para("FactoryID"))
        'modify tianFW 2017/09/13
        If para.Keys.Contains("WorkCenterID") Then
            strsql.AppendFormat(" AND SE.WORKCENTERID='{0}'", para("WorkCenterID"))
        End If
        If para.Keys.Contains("RoleName") Then
            If para("RoleName") = "其他" Then 'add YangJiang 20180725 查询没有角色的人
                strsql.AppendLine("and rd.roleid IS NULL")
            Else
                strsql.AppendFormat(" AND RD.ROLENAME = '{0}'", para("RoleName"))
            End If
        End If
        If para.Keys.Contains("Other") And para.Keys.Contains("FactoryID") Then
            strsql.AppendLine(" AND SE.WORKCENTERID IS NULL AND TEM.TEAMID IS NULL")
        End If
        'add tianFW 
        If para.Keys.Contains("NoTeam") And para.Keys.Contains("FactoryID") Then
            If para.Keys.Contains("TeamID") Then 'add YangJiang 20180725
                strsql.AppendFormat(" AND TEM.TEAMID = '{0}'", para("TeamID"))
            Else
                strsql.AppendLine(" AND TEM.TEAMID IS NULL")
            End If
        End If
        'add tianFW 2017年12月7日
        If para.Keys.Contains("EmployeeID") Then
            strsql.AppendFormat(" AND EM.EMPLOYEEID='{0}'", para("EmployeeID"))
        End If
        'add YangJiang 2018/03/20
        If para.Keys.Contains("ShiftID") Then
            strsql.AppendFormat(" AND EM.SHIFTID='{0}'", para("ShiftID"))
        End If
        'add YangJiang 2018/03/20
        If para.Keys.Contains("noShift") And para.Keys.Contains("FactoryID") Then
            strsql.AppendLine(" AND EM.SHIFTID IS NULL")
        End If


        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql.ToString)
        Return dt
    End Function

    ''' <summary>
    ''' 根据ContainerName 查询批次是否已经存在 add tianFW2017/08/29
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function ISExistContainer(ByVal value As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.ISExistContainer
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT C.*,MF.MFGORDERNAME,F.FACTORYNAME,U.UOMNAME,EM.EMPLOYEENAME AS STARTEMPLOYEENAME,WC.WORKCENTERNAME,")
        strsql.AppendLine("T.TEAMNAME,UA.ATTRIBUTEVALUE TECHNIQUE FROM CONTAINER C")
        strsql.AppendLine("LEFT JOIN MFGORDER MF ON MF.MFGORDERID = C.MFGORDERID")
        strsql.AppendLine("LEFT JOIN CURRENTSTATUS CU ON CU.CURRENTSTATUSID = C.CURRENTSTATUSID")
        strsql.AppendLine("LEFT JOIN FACTORY F ON F.FACTORYID = CU.FACTORYID")
        strsql.AppendLine("LEFT JOIN UOM U ON U.UOMID = C.UOMID")
        strsql.AppendLine("LEFT JOIN EMPLOYEE EM ON EM.EMPLOYEEID = C.STARTEMPLOYEEID")
        strsql.AppendLine("LEFT JOIN WORKCENTER WC ON WC.WORKCENTERID = C.WORKCENTERID")
        strsql.AppendLine("LEFT JOIN TEAM T ON T.TEAMID = C.TEAMID")
        strsql.AppendLine("LEFT JOIN USERATTRIBUTE UA ON UA.PARENTID = C.CONTAINERID AND UA.USERATTRIBUTENAME='CheckTechnique'")
        strsql.AppendFormat("WHERE (C.STATUS=1 OR C.STATUS=2) AND  {0}", value)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql.ToString)
        Return dt
    End Function

    ''' <summary>
    ''' 根据父ContainerID查询ContainerID和ContainerName(关闭批次)
    ''' create tianFW 2017/09/04
    ''' </summary>
    ''' <param name="containerID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetContainerInfoByPerContianerID_close(ByVal containerID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetContainerInfoByPerContianerID_close
        Dim sqlstr As New StringBuilder
        sqlstr.AppendLine("SELECT C.CONTAINERID, C.CONTAINERNAME FROM CONTAINER C")
        sqlstr.AppendFormat(" WHERE C.QTY=1 AND C.STATUS=2 AND C.PARENTCONTAINERID='{0}'", containerID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sqlstr.ToString)
        Return dt
    End Function

    ''' <summary>
    ''' 保存属性
    ''' create:Wangjh 2017-9-4
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SaveUserAttribute(ByVal para As ContainerStartInfo) As uMESProcessResult Implements uLMSCommonIBusiness.SaveUserAttribute

        Dim result As New uMESProcessResult()
        Dim strInfo As String = ""

        Dim m_AttrList As New Dictionary(Of String, List(Of ClientAPIEntity))

        Dim m_AttrChild As New List(Of ClientAPIEntity)

        Dim attEntity As New ClientAPIEntity
        attEntity.ClientDataTypeEnum = DataTypeEnum.DataField
        attEntity.ClientInputTypeEnum = InputTypeEnum.Details
        attEntity.ClientDataName = "Name"
        attEntity.ClientDataValue = para.AttributeName
        m_AttrChild.Add(attEntity)

        attEntity = New ClientAPIEntity()
        attEntity.ClientDataTypeEnum = DataTypeEnum.DataField
        attEntity.ClientInputTypeEnum = InputTypeEnum.Details
        attEntity.ClientDataName = "DataType"
        attEntity.ClientDataValue = "4"
        m_AttrChild.Add(attEntity)

        attEntity = New ClientAPIEntity()
        attEntity.ClientDataTypeEnum = DataTypeEnum.DataField
        attEntity.ClientInputTypeEnum = InputTypeEnum.Details
        attEntity.ClientDataName = "AttributeValue"
        attEntity.ClientDataValue = para.attributeValue

        m_AttrChild.Add(attEntity)

        m_AttrList.Add("0", m_AttrChild)


        Dim m_DataList As New List(Of ClientAPIEntity)

        Dim dataEntity As New ClientAPIEntity

        Dim strSql As String = String.Format("SELECT c.containername,l.containerlevelname FROM CONTAINER c LEFT JOIN CONTAINERLEVEL l ON l.containerlevelid=c.levelid WHERE c.containername='{0}'", para.ContainerName)

        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)

        dataEntity.ClientDataTypeEnum = DataTypeEnum.ContainerField
        dataEntity.ClientInputTypeEnum = InputTypeEnum.Details
        dataEntity.ClientDataName = "Container"
        dataEntity.ClientDataValue = para.ContainerName
        dataEntity.ClientOtherValue = DT.Rows(0)("containerlevelname").ToString().Trim()
        m_DataList.Add(dataEntity)

        Dim daServerHost As ServerHostInfo = para.ServerHostInfo
        Dim serverUser As String = daServerHost.UserName
        Dim serverPassword As String = daServerHost.Password

        Dim api As New CamstarClientAPI(serverUser, serverPassword)

        Dim success As Boolean = api.RunTxnServiceHasSubentity("ContainerAttrMaintDoc", "ContainerAttrMaint", m_DataList, "ServiceDetails", m_AttrList, strInfo)
        result.Result = success
        result.Message = strInfo
        Return result
    End Function

    ''' <summary>
    ''' 保存动态属性
    ''' create:Wangjh 2017-9-4
    ''' </summary>
    ''' <param name="paraList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SaveDenamicAttribute(ByVal paraList As List(Of ContainerStartInfo)) As uMESProcessResult

        Dim result As New uMESProcessResult()
        Dim strInfo As String = ""

        Dim m_AttrList As New Dictionary(Of String, List(Of ClientAPIEntity))

        For i As Integer = 0 To paraList.Count - 1
            Dim m_AttrChild As New List(Of ClientAPIEntity)

            Dim attEntity As New ClientAPIEntity
            attEntity.ClientDataTypeEnum = DataTypeEnum.DataField
            attEntity.ClientInputTypeEnum = InputTypeEnum.Details
            attEntity.ClientDataName = "Name"
            attEntity.ClientDataValue = paraList(i).AttributeName
            m_AttrChild.Add(attEntity)

            attEntity = New ClientAPIEntity()
            attEntity.ClientDataTypeEnum = DataTypeEnum.DataField
            attEntity.ClientInputTypeEnum = InputTypeEnum.Details
            attEntity.ClientDataName = "DataType"
            attEntity.ClientDataValue = "4"
            m_AttrChild.Add(attEntity)

            attEntity = New ClientAPIEntity()
            attEntity.ClientDataTypeEnum = DataTypeEnum.DataField
            attEntity.ClientInputTypeEnum = InputTypeEnum.Details
            attEntity.ClientDataName = "AttributeValue"
            attEntity.ClientDataValue = paraList(i).attributeValue
            m_AttrChild.Add(attEntity)

            m_AttrList.Add(i.ToString().Trim(), m_AttrChild)
        Next

        Dim m_DataList As New List(Of ClientAPIEntity)

        Dim dataEntity As New ClientAPIEntity

        dataEntity.ClientDataTypeEnum = DataTypeEnum.ContainerField
        dataEntity.ClientInputTypeEnum = InputTypeEnum.Details
        dataEntity.ClientDataName = "Container"
        dataEntity.ClientDataValue = paraList(0).ContainerName
        dataEntity.ClientOtherValue = paraList(0).Level
        m_DataList.Add(dataEntity)
        Dim daServerHost As ServerHostInfo = paraList(0).ServerHostInfo
        Dim serverHost As String = daServerHost.ServerHost
        Dim serverPort As String = daServerHost.ServerPort
        Dim serverUser As String = daServerHost.UserName
        Dim serverPassword As String = daServerHost.Password

        Dim api As New CamstarClientAPI(serverUser, serverPassword)

        Dim success As Boolean = api.RunTxnServiceHasSubentity("ContainerAttrMaintDoc", "ContainerAttrMaint", m_DataList, "ServiceDetails", m_AttrList, strInfo)
        result.Result = success
        result.Message = strInfo
        Return result
    End Function

    ''' <summary>
    ''' 设置属性
    ''' create:Wangjh 2017-9-4
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetUserAttribute(ByVal para As ContainerStartInfo) As uMESProcessResult Implements uLMSCommonIBusiness.SetUserAttribute

        Dim result As uMESProcessResult = New uMESProcessResult()

        'Dim strSql As String = String.Format("SELECT c.containerid,c.containername,t.userattributeid,t.attributevalue FROM userattribute  t " & vbCrLf & _
        '                      "LEFT JOIN CONTAINER c ON c.containerid=t.parentid " & vbCrLf & _
        '                      "WHERE t.userattributename='currSpecStatus'AND c.containername='{0}'", para.ContainerName)

        Dim strSql As String = String.Format("SELECT c.containerid,c.containername,t.userattributeid,t.attributevalue,t.userattributename FROM userattribute  t " & vbCrLf & _
                              "LEFT JOIN CONTAINER c ON c.containerid=t.parentid " & vbCrLf & _
                              "WHERE  c.containername='{0}'", para.ContainerName)

        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)

        If DT.Rows.Count = 0 Then
            result = SaveUserAttribute(para)
        Else

            Dim strFilter As String = String.Format("userattributename='{0}'", para.AttributeName)
            Dim tmpRow As DataRow() = DT.Select(strFilter)
            If tmpRow.Length = 0 Then

                Dim attList As List(Of ContainerStartInfo) = New List(Of ContainerStartInfo)

                For Each row As DataRow In DT.Rows
                    Dim tmpEnity As ContainerStartInfo = New ContainerStartInfo()
                    tmpEnity.AttributeName = row("userattributename").ToString().Trim()
                    tmpEnity.attributeValue = row("attributevalue").ToString().Trim()
                    tmpEnity.ContainerName = para.ContainerName
                    tmpEnity.Level = para.Level
                    tmpEnity.ServerHostInfo = para.ServerHostInfo
                    attList.Add(tmpEnity)
                Next
                Dim tmp1Enity As ContainerStartInfo = New ContainerStartInfo()
                tmp1Enity.AttributeName = para.AttributeName
                tmp1Enity.attributeValue = para.attributeValue
                tmp1Enity.ContainerName = para.ContainerName
                tmp1Enity.Level = para.Level
                tmp1Enity.ServerHostInfo = para.ServerHostInfo
                attList.Add(tmp1Enity)

                Dim result1 As uMESProcessResult = SaveDenamicAttribute(attList)
                result.Result = result1.Result
                If result1.Result = False Then
                    result.Message = result1.Message
                End If
            Else
                strSql = String.Format("UPDATE userattribute t SET t.attributevalue='{0}' WHERE t.userattributeid='{1}'", para.attributeValue, tmpRow(0)("userattributeid").ToString().Trim())
                DatabaseHelper.ExecuteSql(strSql)
                result.Result = True
            End If
        End If
        Return result
    End Function

    ''' <summary>
    ''' 更新原批次（被变号）的备注信息 create tianFW 2017-09-04
    ''' </summary>
    ''' <param name="Containers"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetContainerComments(ByVal comments As String, ByVal Containers As String) As Boolean Implements IBusiness.uLMSCommonIBusiness.SetContainerComments
        Dim strsql As String = String.Format("UPDATE CONTAINER C SET C.CONTAINERCOMMENTS='{0}' WHERE {1}", comments, Containers)
        If DatabaseHelper.ExecuteSql(strsql) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' 获取批次变更原因
    ''' crete：Wangjh 2017-9-7
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetChangeStatusReason(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetChangeStatusReason
        Dim strSQL As String
        strSQL = "select t.changestatusreasonname from changestatusreason t "
        Dim dt As New DataTable
        dt = DatabaseHelper.Query_ReturnDatTable(strSQL)
        GetChangeStatusReason = dt
    End Function

    ''' <summary>
    ''' 获取批次数量变更原因
    ''' create:Wangjh 2017-9-7
    ''' </summary>
    Public Function GetQtyAdjustReason() As DataTable Implements uLMSCommonIBusiness.GetQtyAdjustReason
        Dim strSQL As String
        strSQL = "select t.qtyadjustreasonname,t.qtyadjustreasonid from qtyadjustreason t "
        Dim dtMain As New DataTable
        dtMain = DatabaseHelper.Query_ReturnDatTable(strSQL)
        GetQtyAdjustReason = dtMain
    End Function

    ''' <summary>
    ''' 获取产品信息 create tianFW 2017/09/12 用于选择产品
    ''' </summary>
    ''' <param name="strVaule"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetProductInfoLikeNameOrREVISION(ByVal strVaule As String) Implements IBusiness.uLMSCommonIBusiness.GetProductInfoLikeNameOrREVISION
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT  P.PRODUCTID,PB.PRODUCTNAME || ':' || P.PRODUCTREVISION|| '(' || PT.PRODUCTTYPENAME|| ')'  PRODUCTNAME,PB.REVOFRCDID")
        strsql.AppendLine("FROM PRODUCT P")
        strsql.AppendLine("LEFT JOIN PRODUCTBASE PB ON PB.PRODUCTBASEID = P.PRODUCTBASEID")
        strsql.AppendLine("LEFT JOIN PRODUCTTYPE PT ON PT.PRODUCTTYPEID = P.PRODUCTTYPEID")
        If Not String.IsNullOrWhiteSpace(strVaule) Then
            strsql.AppendFormat(" WHERE (PB.PRODUCTNAME LIKE '%{0}%' OR PT.PRODUCTTYPENAME LIKE '%{1}%')", strVaule, strVaule)
        End If
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据员工ID获取员工信息 Create tianFW 2017/09/12
    ''' </summary>
    ''' <param name="EmployeeID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEmployeeByEmployeeID(ByVal EmployeeID As String) As DataTable Implements uLMSCommonIBusiness.GetEmployeeByEmployeeID
        Dim strsql As String = String.Format("SELECT EM.* FROM EMPLOYEE EM WHERE EM.EMPLOYEEID='{0}'", EmployeeID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 根据员工ID获取ReportPage Create tianFW 2017/09/13
    ''' </summary>
    ''' <param name="employeeID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetReportPageByEmployeeID(ByVal employeeID As String) As DataTable Implements uLMSCommonIBusiness.GetReportPageByEmployeeID
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT RP.REPORTPAGENAME FROM REPORTPAGE RP")
        strsql.AppendLine("LEFT JOIN EMPLOYEEREPORTPAGE EP ON RP.REPORTPAGEID = EP.REPORTPAGEID")
        strsql.AppendLine("LEFT JOIN EMPLOYEE EM ON  EP.EMPLOYEEID = EM.EMPLOYEEID")
        strsql.AppendFormat(" WHERE EM.EMPLOYEEID = '{0}'", employeeID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取所有的ReportPage Create tianFW 2017/09/13
    ''' 修改显示逻辑，报表显示所有，看板增加根据厂别显示 Modify by Yuxj20180821
    ''' 修改显示逻辑，报表显示本分厂和无分厂的，看板增加根据厂别显示 Modify by Wangjh20190522
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetReportPageInfo(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetReportPageInfo
        Dim strsql As New StringBuilder
        'strsql.AppendLine("SELECT RP.REPORTPAGENAME FROM REPORTPAGE RP “）
        strsql.AppendLine("SELECT RP.REPORTPAGENAME FROM REPORTPAGE RP  ")
        If para.ContainsKey("FactoryId") Then
            strsql.AppendFormat(" WHERE rp.islookboard=0 and (rp.factoryid is null or rp.factoryid='{0}') ", para("FactoryId"))
            strsql.AppendLine(" union all ")
            strsql.AppendFormat(" SELECT RP.REPORTPAGENAME FROM REPORTPAGE RP WHERE rp.islookboard=1 and rp.factoryid='{0}' ", para("FactoryId"))
        End If

        If para.Count > 0 Then
            '暂时没有条件值（如factoryID）
        End If
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function
    ''' <summary>
    ''' 流水卡扫描
    ''' create:Wangjh 2017-9-14
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ContainerScan(ByVal containerID As String, ByVal ParamArray obj As Object()) As String Implements uLMSCommonIBusiness.ContainerScan
        Dim strSql As String = String.Format(" SELECT containerid,containername,containertype,c.togetherflag FROM container c WHERE c.containerid='{0}'", containerID.ToLower)
        strSql += " AND c.status <> -1 " 'add by tianFW 2018年6月5日
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        Dim containerName As String = ""
        If dt.Rows.Count = 0 Then
            ContainerScan = containerID
            Exit Function
        End If
        containerName = dt.Rows(0)("containername").ToString
        For Each eachObj As Object In obj
            If eachObj = "Report" Then '报工
                ContainerScan = containerName
                Exit Function
            End If
        Next
        If dt.Rows(0)("containertype").ToString = "7" Then '单件单卡
            Dim arrContainerName As String() = containerName.Split("/")
            ContainerScan = String.Concat(arrContainerName.First, "/", arrContainerName.Last.Substring(0, 4))
        Else
            ContainerScan = containerName
        End If
    End Function

    ''' <summary>
    ''' 获取批次信息扫描后返回的数据（批次togetherflag或containername） create by tianFW 2018年6月8日
    ''' </summary>
    ''' <param name="valuestr">传入的是输入的批次ID或Name,返回的是containertype、workflowstepid（当前序）</param>
    ''' <param name="valuename">传入的是"",返回的是批次名称</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetScanContainerInfoReturnData(ByRef valuestr As String, ByRef valuename As String) As String Implements uLMSCommonIBusiness.GetScanContainerInfoReturnData

        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT c.containerid,c.containername,containertype,c.togetherflag,c.workflowstepid ")
        strSql.AppendLine("FROM containercurrentinfo c")
        strSql.AppendFormat(" WHERE Upper(c.containerid)=Upper('{0}') OR Upper(c.containername)=Upper('{0}')", valuestr)
        strSql.AppendLine("AND c.containerstatus <> -1")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql.ToString())
        If dt.Rows.Count = 0 Then
            valuename = valuestr
            Return ""
        End If
        valuestr = dt.Rows(0)("containertype")
        If valuestr = "7" Then
            valuename = dt.Rows(0)("containername")
            valuestr += "," & dt.Rows(0)("workflowstepid")
            Return dt.Rows(0)("togetherflag")
        Else
            valuename = dt.Rows(0)("containername")
            valuestr += "," & dt.Rows(0)("workflowstepid")
            Return dt.Rows(0)("containername")
        End If
    End Function

    ''' <summary>
    ''' 获取重组工艺新版本号createby YangSJ 20170914
    ''' </summary>
    ''' <param name="strWorkflow"></param>
    ''' <param name="strRev"></param>
    ''' <remarks></remarks>
    Sub GetNewRecombineWorkflowRev(ByVal strWorkflow As String, ByRef strRev As String) Implements uLMSCommonIBusiness.GetNewRecombineWorkflowRev
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WF.WORKFLOWREVISION  FROM WORKFLOW WF")
        sb.AppendLine(" LEFT JOIN WORKFLOWBASE WFB    ON WFB.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        sb.AppendFormat("WHERE WFB.WORKFLOWNAME = '{0}'  AND WF.WORKFLOWREVISION LIKE 'CZ%'", strWorkflow)
        sb.AppendLine("  ORDER BY WF.WORKFLOWREVISION DESC")
        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        Dim intarray As Integer = 0
        If DT.Rows.Count > 0 Then
            Dim row As DataRow = DT.Rows(0)
            strRev = row("WORKFLOWREVISION").ToString().Trim().Replace("CZ", "")
            If Integer.TryParse(strRev, intarray) Then
                intarray += 1
            End If
        End If

        strRev = "CZ" + intarray.ToString("D3")
    End Sub
    ''' <summary>
    ''' 创建工艺路线createby YangSJ 20170914
    ''' </summary>
    ''' <param name="para"></param>
    ''' <param name="dtStepList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function CreateWorkflowRev(ByVal para As Dictionary(Of String, String), ByVal dtStepList As DataTable) As ResultStatus Implements uLMSCommonIBusiness.CreateWorkflowRev
        Dim strInfo As String = ""
        CreateWorkflowRev = New ResultStatus
        Dim m_DataList As New List(Of ClientAPIEntity)
        m_DataList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkflowName"), ""))
        m_DataList.Add(New ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, para("Rev"), ""))
        m_DataList.Add(New ClientAPIEntity("Description", InputTypeEnum.Details, DataTypeEnum.DataField, para("Description"), ""))
        If para.ContainsKey("ProductName") Then
            m_DataList.Add(New ClientAPIEntity("Product", InputTypeEnum.Details, DataTypeEnum.RevisionedObjectField, para("ProductName"), para("ProductRev")))
        End If
        m_DataList.Add(New ClientAPIEntity("Factory", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("Factory"), ""))
        If para.ContainsKey("WorkFlowType") Then
            m_DataList.Add(New ClientAPIEntity("WorkFlowType", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkFlowType"), ""))
        End If
        If para.ContainsKey("ProcessNo") Then 'add:Wangjh 20220914
            m_DataList.Add(New ClientAPIEntity("Process_no", InputTypeEnum.Details, DataTypeEnum.DataField, para("ProcessNo"), ""))
        End If

        'Modify by zhangrj20250620
        If para.ContainsKey("WorkflowType2") Then '工艺类型2
            m_DataList.Add(New ClientAPIEntity("WorkflowType2", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkflowType2"), ""))
        End If

        'Modify by zhangrj20250620
        If para.ContainsKey("PartRevID") Then '设计图版次
            m_DataList.Add(New ClientAPIEntity("Part_RevID", InputTypeEnum.Details, DataTypeEnum.DataField, para("PartRevID"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("TaskNo") Then '任务号/批次号（工装工具）
            m_DataList.Add(New ClientAPIEntity("TaskNo", InputTypeEnum.Details, DataTypeEnum.DataField, para("TaskNo"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("BjQty") Then '备件数量（工装工具）
            m_DataList.Add(New ClientAPIEntity("BjQty", InputTypeEnum.Details, DataTypeEnum.DataField, para("BjQty"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("Qty") Then '在制数（工装工具）
            m_DataList.Add(New ClientAPIEntity("Qty", InputTypeEnum.Details, DataTypeEnum.DataField, para("Qty"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("WorkCenterName") Then '工区（工装工具）
            m_DataList.Add(New ClientAPIEntity("WorkCenter", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("WorkCenterName"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("MaterialSize") Then '毛料数量（工装工具）
            m_DataList.Add(New ClientAPIEntity("mlsl", InputTypeEnum.Details, DataTypeEnum.DataField, para("MaterialSize"), ""))
        End If

        Dim strWorkflowName As String = para("WorkflowName")
        Dim strOldRevsion As String = para("OldRev")
        Dim strRevsion As String = para("Rev")
        Dim serverUser As String = para("UserName")
        Dim serverPassword As String = para("Password")

        Dim api As New CamstarClientAPI(serverUser, serverPassword)
        CreateWorkflowRev.IsError = Not api.CreateNewWorkflowRevsion(strWorkflowName, strOldRevsion, strRevsion, m_DataList, dtStepList, strInfo)
        CreateWorkflowRev.Message = strInfo
    End Function

    ''' <summary>
    ''' 根据Spec工序的ID或者版本+名称获取工序信息
    ''' </summary>
    ''' <param name="SpecName">工序名称</param>
    ''' <param name="SpecRev">工序版本</param>
    ''' <param name="SpecID">工序ID</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetSpecInfo(ByVal SpecName As String, ByVal SpecRev As String, ByVal SpecID As String) Implements uLMSCommonIBusiness.GetSpecInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT sb.specname,sb.revofrcdid,s.* FROM spec s ")
        strsql.AppendLine("LEFT JOIN specbase sb ON sb.specbaseid = s.specbaseid")
        If Not String.IsNullOrWhiteSpace(SpecID) Then
            strsql.AppendFormat("WHERE  s.specid='{0}'", SpecID)
        ElseIf Not String.IsNullOrWhiteSpace(SpecName) And String.IsNullOrWhiteSpace(SpecRev) Then
            strsql.AppendFormat("WHERE  sb.specname='{0}'", SpecName)
        Else
            strsql.AppendFormat("WHERE  s.specrevision='{0}' AND sb.specname='{1}'", SpecRev, SpecName)
        End If
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 创建工序createby YangSJ 20170914
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function CreateSpec(ByVal para As Dictionary(Of String, String)) As ResultStatus Implements uLMSCommonIBusiness.CreateSpec
        Dim strInfo As String = ""
        CreateSpec = New ResultStatus
        Dim m_DataList As New List(Of ClientAPIEntity)
        m_DataList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecName"), ""))
        m_DataList.Add(New ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecRev"), ""))
        m_DataList.Add(New ClientAPIEntity("SpecNo", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecNO"), ""))
        m_DataList.Add(New ClientAPIEntity("Operation", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("Operation"), ""))
        m_DataList.Add(New ClientAPIEntity("Factory", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("Factory"), ""))
        m_DataList.Add(New ClientAPIEntity("OPDesc", InputTypeEnum.Details, DataTypeEnum.DataField, para("OPDesc"), ""))
        If para.ContainsKey("SpecDesc") Then
            If Not String.IsNullOrWhiteSpace(para("SpecDesc")) Then
                m_DataList.Add(New ClientAPIEntity("Description", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecDesc"), ""))
            End If
        End If
        'Modify by Yuxj20180727 修改判断条件
        'If para("Iskey") IsNot Nothing Then
        '    m_DataList.Add(New ClientAPIEntity("IsKey", InputTypeEnum.Details, DataTypeEnum.DataField, para("Iskey"), ""))
        'End If
        'If para("IsLastCheck") IsNot Nothing Then
        '    m_DataList.Add(New ClientAPIEntity("LastCheck", InputTypeEnum.Details, DataTypeEnum.DataField, para("IsLastCheck"), ""))
        'End If
        'If para("ControlCode") IsNot Nothing Then
        '    m_DataList.Add(New ClientAPIEntity("ControlCode", InputTypeEnum.Details, DataTypeEnum.DataField, para("ControlCode"), ""))
        'End If
        If para.ContainsKey("Iskey") Then
            m_DataList.Add(New ClientAPIEntity("IsKey", InputTypeEnum.Details, DataTypeEnum.DataField, para("Iskey"), ""))
        End If
        If para.ContainsKey("IsLastCheck") Then
            m_DataList.Add(New ClientAPIEntity("LastCheck", InputTypeEnum.Details, DataTypeEnum.DataField, para("IsLastCheck"), ""))
        End If
        If para.ContainsKey("ControlCode") Then
            m_DataList.Add(New ClientAPIEntity("ControlCode", InputTypeEnum.Details, DataTypeEnum.DataField, para("ControlCode"), ""))
        End If

        Dim serverUser As String = para("UserName")
        Dim serverPassword As String = para("Password")

        Dim api As New CamstarClientAPI(serverUser, serverPassword)
        CreateSpec.IsError = Not api.CreateModelByStandard("SpecMaintDoc", "SpecMaint", "New", m_DataList, strInfo)
        CreateSpec.Message = strInfo
    End Function

    ''' <summary>
    ''' 创建工序createby tianFW  2018年7月23日
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function CreateNewRevSpec(ByVal para As Dictionary(Of String, String)) As ResultStatus Implements uLMSCommonIBusiness.CreateNewRevSpec
        Dim strInfo As String = ""
        CreateNewRevSpec = New ResultStatus
        Dim m_DataList As New List(Of ClientAPIEntity)
        m_DataList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecName"), ""))
        m_DataList.Add(New ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecRev"), ""))
        m_DataList.Add(New ClientAPIEntity("SpecNo", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecNO"), ""))
        m_DataList.Add(New ClientAPIEntity("Operation", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("Operation"), ""))
        m_DataList.Add(New ClientAPIEntity("Factory", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("Factory"), ""))
        m_DataList.Add(New ClientAPIEntity("OPDesc", InputTypeEnum.Details, DataTypeEnum.DataField, para("OPDesc"), ""))
        If para.ContainsKey("SpecDesc") Then
            If Not String.IsNullOrWhiteSpace(para("SpecDesc")) Then
                m_DataList.Add(New ClientAPIEntity("Description", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecDesc"), ""))
            End If
        End If

        If para.ContainsKey("Iskey") Then
            If para("Iskey") IsNot Nothing Then
                m_DataList.Add(New ClientAPIEntity("IsKey", InputTypeEnum.Details, DataTypeEnum.DataField, para("Iskey"), ""))
            End If
        End If

        If para.ContainsKey("IsLastCheck") Then
            If para("IsLastCheck") IsNot Nothing Then
                m_DataList.Add(New ClientAPIEntity("LastCheck", InputTypeEnum.Details, DataTypeEnum.DataField, para("IsLastCheck"), ""))
            End If
        End If

        If para.ContainsKey("ControlCode") Then
            If para("ControlCode") IsNot Nothing Then
                m_DataList.Add(New ClientAPIEntity("ControlCode", InputTypeEnum.Details, DataTypeEnum.DataField, para("ControlCode"), ""))
            End If
        End If
        Dim serverUser As String = para("UserName")
        Dim serverPassword As String = para("Password")

        Dim api As New CamstarClientAPI(serverUser, serverPassword)
        CreateNewRevSpec.IsError = Not api.CreateNewModelRevision("SpecMaint", para("SpecName"), para("SpecOldRev"), m_DataList, Nothing, strInfo)
        CreateNewRevSpec.Message = strInfo
    End Function


    ''' <summary>
    ''' 更新员工的设备和报表信息 create tianFW　2017/09/15
    ''' </summary>
    ''' <param name="dtResource"></param>
    ''' <param name="dtReportPage"></param>
    ''' <param name="para"></param>
    ''' <param name="strInfo"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>Modify by YangJiang 20180614 ByVal t_Type As String
    Function UpdateUserResourceAndReportPage(ByVal dtResource As DataTable, ByVal dtReportPage As DataTable, ByVal para As Dictionary(Of String, String), ByRef strInfo As String, ByVal t_Type As String) As Boolean Implements uLMSCommonIBusiness.UpdateUserResourceAndReportPage
        UpdateUserResourceAndReportPage = False
        Dim UserName As String = para("UserName")
        Dim Password As String = para("Password")
        Dim strTxnDocName, strTxnName As String
        strTxnDocName = "EmployeeMaintDoc"
        strTxnName = "EmployeeMaint"
        Dim DataEntityList As New List(Of ClientAPIEntity)
        DataEntityList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("EmployeeName"), ""))

        Dim ResourceList_re As New Dictionary(Of Integer, String)
        Dim ResourceList_rp As New Dictionary(Of Integer, String)
        'Modify by YangJiang 20180614 根据传参判断是更新设备还是报表
        If t_Type = "1" Then
            For i As Integer = 0 To dtResource.Rows.Count - 1
                ResourceList_re.Add(i, dtResource(i)("ResourceName"))
            Next
            DataEntityList.Add(New ClientAPIEntity("ResourceList", InputTypeEnum.Details, DataTypeEnum.NamedObjectList, ResourceList_re, "", para("ResourceCount")))
        ElseIf t_Type = "2" Then
            For i As Integer = 0 To dtReportPage.Rows.Count - 1
                ResourceList_rp.Add(i, dtReportPage(i)("ReportName"))
            Next
            DataEntityList.Add(New ClientAPIEntity("ReportPage", InputTypeEnum.Details, DataTypeEnum.NamedObjectList, ResourceList_rp, "", para("ReportPageCount")))
        End If



        'Dim index As Integer = 0
        'Dim CheckPointEntity As New Dictionary(Of String, Dictionary(Of String, List(Of ClientAPIEntity)))
        'Dim subList As List(Of ClientAPIEntity)
        'Dim SubentityList As Dictionary(Of String, List(Of ClientAPIEntity))

        'SubentityList = New Dictionary(Of String, List(Of ClientAPIEntity))
        'For Each row As DataRow In dtResource.Rows
        '    subList = New List(Of ClientAPIEntity)
        '    subList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, row("ResourceName"), ""))
        '    SubentityList.Add(index.ToString(), subList)
        '    index += 1
        'Next
        'CheckPointEntity.Add("ResourceList", SubentityList)

        'index = 0
        'SubentityList = New Dictionary(Of String, List(Of ClientAPIEntity))
        'For Each row As DataRow In dtReportPage.Rows
        '    subList = New List(Of ClientAPIEntity)
        '    subList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, row("ReportName"), ""))
        '    SubentityList.Add(index.ToString(), subList)
        '    index += 1
        'Next
        'CheckPointEntity.Add("ReportPage", SubentityList)

        Dim api As New CamstarClientAPI(UserName, Password)
        Dim para_ As New Dictionary(Of String, Integer)
        UpdateUserResourceAndReportPage = api.UpdateModelByStandard(strTxnDocName, strTxnName, para("EmployeeName"), "", DataEntityList, strInfo)
        'para_.Add("ResourceList", Integer.Parse(para("ResourceCount")))
        'para_.Add("ReportPage", Integer.Parse(para("ReportPageCount")))
        'UpdateUserResourceAndReportPage = api.UpdateModelHasMoreSubentityList(strTxnDocName, strTxnName, para("EmployeeName"), "", "NDO", DataEntityList, CheckPointEntity, para_, strInfo)
    End Function

    ''' <summary>
    ''' create tianFW 2017/09/18 删除重组工艺
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function DelWorkflow(ByVal para As Dictionary(Of String, String)) As String Implements uLMSCommonIBusiness.DelWorkflow
        Dim infostr As String = ""
        Dim strTxnDocName As String = "WorkflowMaintDoc"
        Dim strTxnName As String = "WorkflowMaint"
        Dim UserName As String = para("UserName")
        Dim Password As String = para("Password")
        Dim api As New CamstarClientAPI(UserName, Password)
        api.DeleteModel(strTxnDocName, strTxnName, para("WorkflowName"), para("Rev"), "RO", infostr)
        Return infostr
    End Function

    ''' <summary>
    ''' 根据workflowid 获取在Historymainline有多少行数据 create tianFW 2017/09/18
    ''' </summary>
    ''' <param name="workflowid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetcountinHistorymainline(ByVal workflowid As String) As DataTable Implements uLMSCommonIBusiness.GetcountinHistorymainline
        Dim strsql As String =
            <string>
                SELECT COUNT(WF.WORKFLOWID) COUNT_
                FROM HISTORYMAINLINE HM
                LEFT JOIN WORKFLOWSTEP WS ON HM.WORKFLOWSTEPID = WS.WORKFLOWSTEPID
                LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = WS.WORKFLOWID
            </string>
        strsql += String.Format(" WHERE WF.WORKFLOWID='{0}'", workflowid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 根据workflowID获取workflow Info create tianFW 2017/09/18
    ''' </summary>
    ''' <param name="workflowid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkflowInfobyWorkflowID(ByVal workflowid As String) As DataTable Implements uLMSCommonIBusiness.GetWorkflowInfobyWorkflowID
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT WF.*,EM.EMPLOYEENAME CRAFTER,EM.FULLNAME FULLCRAFTER,wb.workflowname FROM WORKFLOW WF")
        strsql.AppendLine("LEFT JOIN EMPLOYEE EM ON EM.EMPLOYEEID = WF.ZGEMPLOYEEID")
        strsql.AppendLine("LEFT JOIN workflowbase wb ON wb.workflowbaseid=wf.workflowbaseid")
        strsql.AppendFormat("WHERE WF.WORKFLOWID='{0}'", workflowid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 更新Spec表的NC信息  create tianFW 2017/09/26
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function UpdateSpecNCInfo(ByVal para As Dictionary(Of String, String)) As Boolean Implements uLMSCommonIBusiness.UpdateSpecNCInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine(" UPDATE SEPC S SET")
        strsql.AppendFormat(" S.NCCODE='{0}'", para("NCCode"))
        strsql.AppendFormat(" WHERE S.SPECID='{0}'", para("SpecID"))
        If DatabaseHelper.ExecuteSql(strsql.ToString()) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 获取汇总表中的节点信息 create tianFW 2017/09/29
    ''' </summary>
    ''' <param name="Containerid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetStepCheckNum(ByVal Value As String, ByVal Containerid As String) As DataTable Implements uLMSCommonIBusiness.GetStepCheckNum
        GetStepCheckNum = New DataTable
        If Value = "First" Then
            Return DatabaseHelper.Query_ReturnDatTable(String.Format("SELECT C.FIRSTCHECKNUM,C.WORKFLOWSTEPID,c.qty,c.containerstatus FROM CONTAINERCURRENTINFO C WHERE C.CONTAINERID='{0}'", Containerid))
        ElseIf Value = "Other" Then
            Return DatabaseHelper.Query_ReturnDatTable(String.Format("SELECT C.STEPCHECKNUM,C.WORKFLOWSTEPID,c.qty,c.containerstatus FROM CONTAINERCURRENTINFO C WHERE C.CONTAINERID='{0}'", Containerid))
        ElseIf Value = "Noncon" Then
            Return DatabaseHelper.Query_ReturnDatTable(String.Format("SELECT C.NONCONFORMINGNUM,C.WORKFLOWSTEPID FROM CONTAINERCURRENTINFO C WHERE C.CONTAINERID='{0}'", Containerid))
        ElseIf Value = "Split" Then
            Return DatabaseHelper.Query_ReturnDatTable(String.Format("SELECT C.SPLITNUM FROM CONTAINERCURRENTINFO C WHERE C.CONTAINERID='{0}'", Containerid))
        End If
    End Function

    ''' <summary>
    ''' 更新分批之后新批次的TOGETHERFLAG create tianFW 2017/09/29
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function UpdateSplitContainerTogeTherFlag(ByVal containername As String) As Boolean Implements uLMSCommonIBusiness.UpdateSplitContainerTogeTherFlag
        Return DatabaseHelper.ExecuteSql(String.Format("UPDATE CONTAINER C SET C.TOGETHERFLAG ='{0}' WHERE C.CONTAINERNAME='{1}'", containername, containername))
    End Function

    ''' <summary>
    ''' 获取工艺上的班组信息
    ''' </summary>
    ''' <param name="workflowID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowTeam(ByVal workflowID As String) As DataTable Implements uLMSCommonIBusiness.GetWorkFlowTeam
        Dim strSql As String = String.Format(" SELECT w.teamid FROM Workflow w WHERE w.workflowid='{0}'", workflowID)
        Dim dt As New DataTable
        dt = DatabaseHelper.Query_ReturnDatTable(strSql)
        GetWorkFlowTeam = dt
    End Function

    ''' <summary>
    '''更新工序上的班组信息
    ''' </summary>
    ''' <param name="workflowStepID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function UpdateWorkFlowStepTeam(ByVal workflowStepID As String, ByVal teamID As String) As Boolean Implements uLMSCommonIBusiness.UpdateWorkFlowStepTeam
        Dim strSql As String = String.Format(" UPDATE workflowstep ws SET ws.teamid='{0}' WHERE ws.workflowstepid='{1}' AND ws.teamid IS NULL", teamID, workflowStepID)
        Dim i As Integer
        i = DatabaseHelper.ExecuteSql(strSql)
        If i > 0 Then
            UpdateWorkFlowStepTeam = True
        Else
            UpdateWorkFlowStepTeam = False
        End If
    End Function

    ''' <summary>
    ''' 获取工序关键过程控制文档信息 create tianFW 2017/10/17
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowSetpsOfKeyProcessByWorkflowID(ByVal strWorkflowID As String, ByVal strWorkflowStepID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowSetpsOfKeyProcessByWorkflowID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WT.WORKFLOWSTEPID,WT.WORKFLOWSTEPNAME,WT.SEQUENCE,KCC.KEYPROCESSCONTROLDOCNAME")
        sb.AppendLine("FROM WORKFLOWSTEP WT")
        sb.AppendLine("LEFT JOIN KEYPROCESSCONTROLDOCSTEP KS ON KS.WORKFLOWSTEPID = WT.WORKFLOWSTEPID")
        sb.AppendLine("LEFT JOIN KEYPROCESSCONTROLDOC KCC ON KCC.KEYPROCESSCONTROLDOCID = KS.KEYPROCESSCONTROLDOCID")
        If Not String.IsNullOrWhiteSpace(strWorkflowID) Then
            sb.AppendFormat(" WHERE WT.WORKFLOWID= '{0}'", strWorkflowID)
        End If
        If Not String.IsNullOrWhiteSpace(strWorkflowStepID) Then
            sb.AppendFormat(" AND WT.WORKFLOWSTEPID= '{0}'", strWorkflowStepID)
        End If
        sb.AppendLine(" ORDER BY WT.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetWorkFlowSetpsOfKeyProcessByWorkflowID = New DataTable
        Else
            GetWorkFlowSetpsOfKeyProcessByWorkflowID = dt
        End If
    End Function

    ''' <summary>
    ''' 添加工序与关键过程文档控制的关联信息 create tianFW 2017/10/17
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function AddKeyProcessControlDocStepInfo(ByVal keyProcessControlDocID As String, ByVal workflowStepID As String) As Boolean Implements uLMSCommonIBusiness.AddKeyProcessControlDocStepInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine(" INSERT INTO KEYPROCESSCONTROLDOCSTEP(KEYPROCESSCONTROLDOCID,WORKFLOWSTEPID)")
        strsql.AppendLine("VALUES(:KEYPROCESSCONTROLDOCID,:WORKFLOWSTEPID)")
        Dim insertpara(1) As OracleParameter
        insertpara(0) = DatabaseHelper.NewParameter(":KEYPROCESSCONTROLDOCID", keyProcessControlDocID, OracleType.VarChar)
        insertpara(1) = DatabaseHelper.NewParameter(":WORKFLOWSTEPID", workflowStepID, OracleType.VarChar)
        If DatabaseHelper.ExecuteSql(strsql.ToString(), insertpara) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 根据工序ID删除工序与关键过程文档控制的关联信息 create tianFW 2017/10/17
    ''' </summary>
    ''' <param name="workflowStepIDs"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DelKeyProcessControlDocStepInfo(ByVal workflowStepIDs As String) As Boolean Implements uLMSCommonIBusiness.DelKeyProcessControlDocStepInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine(" DELETE FROM KEYPROCESSCONTROLDOCSTEP KS")
        strsql.AppendFormat(" WHERE {0}", workflowStepIDs)
        If DatabaseHelper.ExecuteSql(strsql.ToString()) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 通过WorkflowStepID获取工序信息 create tianFW 2017/10/22
    ''' </summary> 
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowSetpsByWorkflowStepID(ByVal WorkflowStepID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowSetpsByWorkflowStepID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WT.WORKFLOWSTEPID,WT.WORKFLOWSTEPNAME,WT.SEQUENCE,WT.WORKCENTERID,WC.WORKCENTERNAME,T.TEAMID,T.TEAMNAME") ',EM.EMPLOYEENAME CRAFTER
        sb.AppendLine("FROM WORKFLOWSTEP WT")
        'sb.AppendLine("LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = WF.WORKFLOWID")
        'sb.AppendLine("LEFT JOIN EMPLOYEE EM ON EM.EMPLOYEEID = WF.ZGEMPLOYEEID")
        sb.AppendLine("LEFT JOIN WORKCENTER WC ON WC.WORKCENTERID= WT.WORKCENTERID")
        sb.AppendLine("LEFT JOIN TEAM T ON WT.TEAMID = T.TEAMID")
        sb.AppendFormat(" WHERE WT.WORKFLOWSTEPID= '{0}'", WorkflowStepID)
        sb.AppendLine("ORDER BY WT.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If dt Is Nothing Then
            GetWorkFlowSetpsByWorkflowStepID = New DataTable
        Else
            GetWorkFlowSetpsByWorkflowStepID = dt
        End If
    End Function

    ''' <summary>
    ''' 更新工艺是否存在图纸的状态 create tianFW 2017/10/24
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UpdateWFIsExitPrint(ByVal workflowid As String, ByVal value As String) Implements uLMSCommonIBusiness.UpdateWFIsExitPrint
        Dim strsql As New StringBuilder
        If value = "" Then
            strsql.AppendLine("UPDATE WORKFLOW WF SET WF.HASBLUEPRINT=NULL")
        Else
            strsql.AppendFormat("UPDATE WORKFLOW WF SET WF.HASBLUEPRINT='{0}'", value)
        End If
        strsql.AppendFormat(" WHERE WF.WORKFLOWID='{0}'", workflowid)
        If DatabaseHelper.ExecuteSql(strsql.ToString()) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 更新工艺的ZGEMPLOYEEID create tianFW 2017/10/26
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UpdateWorkflowInfo(ByVal para As Dictionary(Of String, String)) As Boolean Implements uLMSCommonIBusiness.UpdateWorkflowInfo
        Dim strsql As New StringBuilder
        strsql.AppendFormat("UPDATE WORKFLOW W SET W.ZGEMPLOYEEID='{0}'", para("ZGEmployeeID"))
        strsql.AppendFormat(" WHERE W.WORKFLOWID ='{0}'", para("WorkflowID"))
        If DatabaseHelper.ExecuteSql(strsql.ToString()) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' 通过API更新工艺信息
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function UpdateWorkflowInfoByApi(ByVal para As Dictionary(Of String, Object)) As ResultStatus Implements uLMSCommonIBusiness.UpdateWorkflowInfoByApi
        Dim m_DataList As New List(Of ClientAPIEntity)
        If para.ContainsKey("WorkflowName") Then
            m_DataList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkflowName"), ""))
        End If
        If para.ContainsKey("Revision") Then
            m_DataList.Add(New ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, para("Revision"), ""))
        End If
        If para.ContainsKey("Status") Then
            m_DataList.Add(New ClientAPIEntity("Status", InputTypeEnum.Details, DataTypeEnum.DataField, para("Status"), ""))
        End If
        Dim api As New CamstarClientAPI(para("UserName"), para("Password"))
        Dim strInfo As String = ""
        UpdateWorkflowInfoByApi = New ResultStatus
        UpdateWorkflowInfoByApi.IsError = api.UpdateModel("MachineMfgWorkFlowMaint", para("WorkflowName"), para("Revision"), m_DataList, Nothing, strInfo)
        UpdateWorkflowInfoByApi.Message = strInfo
    End Function

    ''' <summary>
    ''' 根据工艺name和Rev获取工艺信息 createtianFW 2017/10/26
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkflowInfoByNameAndRev(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetWorkflowInfoByNameAndRev
        Dim strsql As New StringBuilder
        If para.Keys.Contains("Rev") And para.Keys.Contains("WorkflowName") Then '如果存在版本
            strsql.AppendLine("SELECT * FROM WORKFLOW W")
            strsql.AppendLine("LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID = W.WORKFLOWBASEID")
            strsql.AppendFormat(" WHERE WB.WORKFLOWNAME='{0}' AND W.WORKFLOWREVISION='{1}'", para("WorkflowName"), para("Rev"))
        ElseIf para.Keys.Contains("WorkflowID") And para.Keys.Contains("ProductID") Then
            strsql.AppendLine("SELECT wf.workflowid,wf.workflowbaseid from WORKFLOW wf")
            strsql.AppendFormat("WHERE wf.workflowid='{0}'", para("WorkflowID"))
            Dim dt_workflow As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
            If dt_workflow.Rows().Count > 0 Then
                Dim dt_other As DataTable = GetWorkFlowOtherRevision(para("WorkflowID"), dt_workflow.Rows(0)("workflowbaseid"))
                'add:Wangjh 20181127 增加分厂筛选
                If para.ContainsKey("FactoryID") Then
                    dt_other.DefaultView.RowFilter = "FactoryID='" + para("FactoryID") + "'"
                    dt_other = dt_other.DefaultView.ToTable()
                End If
                '
                Return dt_other
            Else
                Return New DataTable
            End If
        ElseIf para.Keys.Contains("WorkflowName") And para.Keys.Count = 1 Then '如果只存在工艺名称
            strsql.AppendLine("SELECT wb.WorkflowName,w.workflowid,w.workflowrevision,w.workflowtype FROM WORKFLOW W")
            strsql.AppendLine("LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID = W.WORKFLOWBASEID")
            strsql.AppendFormat(" WHERE WB.WORKFLOWNAME='{0}' ", para("WorkflowName"))
        End If
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取已经存在的订单信息 create tianfW 2017/10/31
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsExistMfgOrderInfo(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.IsExistMfgOrderInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT M.MFGORDERNAME, M.MFGORDERID,F.FACTORYNAME,M.PLANNEDSTARTDATE,M.PLANNEDCOMPLETIONDATE,")
        strsql.AppendLine("PB.PRODUCTNAME,OT.ORDERTYPENAME,M.QTY,UA.ATTRIBUTEVALUE MRPCONTROLER")
        strsql.AppendLine("FROM MFGORDER M")
        strsql.AppendLine("LEFT JOIN FACTORY F ON F.FACTORYID = M.FACTORYID")
        strsql.AppendLine("LEFT JOIN PRODUCTBASE PB_ ON PB_.PRODUCTBASEID = M.PRODUCTBASEID")
        strsql.AppendLine("LEFT JOIN PRODUCT P ON P.PRODUCTID = NVL(PB_.REVOFRCDID,M.PRODUCTID)")
        strsql.AppendLine("LEFT JOIN PRODUCTBASE PB ON PB.PRODUCTBASEID = P.PRODUCTBASEID")
        strsql.AppendLine("LEFT JOIN ORDERTYPE OT ON OT.ORDERTYPEID = M.ORDERTYPEID")
        strsql.AppendLine("LEFT JOIN USERATTRIBUTE UA ON UA.PARENTID = M.MFGORDERID AND UA.USERATTRIBUTENAME='MRP控制者'")
        strsql.AppendFormat(" WHERE {0}", para("value"))
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString)
    End Function

    ''' <summary>
    ''' 根据订单ID获取该订单已创建的批次的类型 create tianFW 2017/10/31
    ''' </summary>
    ''' <param name="MfgOrderID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetContainerTypeByMfgOrderID(ByVal MfgOrderID As String) As DataTable Implements uLMSCommonIBusiness.GetContainerTypeByMfgOrderID
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT M.MFGORDERNAME, C.CONTAINERNAME, DECODE(C.CONTAINERTYPE,'2','批量加工','3','批量带子序号'，'7','单件加工') CONTAINERTYPE")
        strsql.AppendLine("FROM MFGORDER M")
        strsql.AppendLine("LEFT JOIN CONTAINER C ON M.MFGORDERID = C.MFGORDERID")
        strsql.AppendLine("WHERE C.CONTAINERTYPE IS NOT NULL")
        strsql.AppendFormat(" AND M.MFGORDERID='{0}' AND C.STATUS=1", MfgOrderID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据件号Name查询件号在数据库中是否存在 create tianFW 2017/10/31
    ''' </summary>
    ''' <param name="ProductNames"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsExistProduct(ByVal ProductNames As String) As DataTable Implements uLMSCommonIBusiness.IsExistProduct
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT P.PRODUCTID,PB.PRODUCTNAME,P.PRODUCTREVISION FROM PRODUCT P")
        strsql.AppendLine("LEFT JOIN PRODUCTBASE PB ON PB.REVOFRCDID = P.PRODUCTID")
        strsql.AppendFormat(" WHERE {0}", ProductNames)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据车间Name查询车间在数据库中是否存在 create tianFW 2017/10/31
    ''' </summary>
    ''' <param name="FactotryNames"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsExistFactotry(ByVal FactotryNames As String) As DataTable Implements uLMSCommonIBusiness.IsExistFactotry
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT F.FACTORYNAME, F.FACTORYID FROM FACTORY F")
        strsql.AppendFormat(" WHERE {0}", FactotryNames)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据车间Name和工区Name查询工区在数据库中是否存在 create tianFW 2017/10/31
    ''' </summary>
    ''' <param name="WorkCenterNames"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsExistWorkCenter(ByVal WorkCenterNames As String) As DataTable Implements uLMSCommonIBusiness.IsExistWorkCenter
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT F.FACTORYNAME,F.FACTORYID,WC.WORKCENTERID,WC.WORKCENTERNAME FROM FACTORY F")
        strsql.AppendLine("LEFT JOIN WORKCENTER WC ON WC.FACTORYID = F.FACTORYID")
        strsql.AppendFormat(" WHERE {0}", WorkCenterNames)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据件号获取默认件号版本 create tianFW 2017/11/01
    ''' </summary>
    ''' <param name="ProductName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetDefaultProductInfo(ByVal ProductName As String) As DataTable Implements uLMSCommonIBusiness.GetDefaultProductInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT P.PRODUCTID,PB.PRODUCTNAME,P.PRODUCTREVISION FROM PRODUCT P")
        strsql.AppendLine("LEFT JOIN PRODUCTBASE PB ON PB.REVOFRCDID = P.PRODUCTID")
        strsql.AppendFormat(" WHERE PB.PRODUCTNAME='{0}'", ProductName)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据工艺Name获取默认的工艺信息 create tianFW2017/11/01
    ''' </summary>
    ''' <param name="workflowname"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetDefaultWorkflowInfo(ByVal workflowname As String) As DataTable Implements uLMSCommonIBusiness.GetDefaultWorkflowInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT WF.WORKFLOWID,WF.WORKFLOWREVISION FROM WORKFLOW WF")
        strsql.AppendLine("LEFT JOIN WORKFLOWBASE WB ON WF.WORKFLOWID = WB.REVOFRCDID")
        strsql.AppendFormat(" WHERE WB.WORKFLOWNAME = '{0}'", workflowname)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取订单类型是否存在的表 create tianFW 2017/11/2
    ''' </summary>
    ''' <param name="mfgTypes"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function IsExistMfgType(ByVal mfgTypes As String) As DataTable Implements uLMSCommonIBusiness.IsExistMfgType
        Dim strsql As New StringBuilder
        strsql.AppendFormat(" SELECT OT.ORDERTYPENAME,OT.ORDERTYPEID FROM ORDERTYPE OT WHERE  {0}", mfgTypes)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取批次超越单信息
    ''' create:Wangjh 20171123
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function QuerySurpassBillInfo(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.QuerySurpassBillInfo
        Dim strSql As String = <string>
                                  SELECT DISTINCT (sbi.productname||'/'||sbi.containername) containername,sbi.processno workflowname,sbm.specno,sbd.remark,sbi.* FROM surpassbillinfo sbi 
                                  LEFT JOIN surpassbilldetail sbd ON sbd.surpassbillinfoid=SBI.surpassbillinfoid--明细
                                  LEFT JOIN surpassbillmapping sbm  ON sbm.surpassbilldetailid=sbd.surpassbilldetailid--映射
                              </string>
        strSql += String.Format(" WHERE sbm.containerid in ({0})  ", para("ContainerID"))
        If para.ContainsKey("ProductName") Then
            strSql += String.Format("  AND sbi.productname='{0}' ", para("ProductName"))
        End If
        If para.ContainsKey("ProcessNo") Then
            strSql += String.Format(" AND sbi.processno='{0}'", para("ProcessNo"))
        End If
        If para.ContainsKey("SpecNo") Then
            strSql += String.Format(" AND sbm.specno={0}", para("SpecNo"))
        End If
        QuerySurpassBillInfo = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 根据工艺ID获取工艺名称
    ''' create:Wangjh 20171123
    ''' </summary>
    ''' <param name="workfLowID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowNameByWorkFLowID(ByVal workfLowID As String) As DataTable Implements uLMSCommonIBusiness.GetWorkFlowNameByWorkFLowID
        Dim strSql As String = <string>
                                SELECT wb.workflowname,w.* FROM workflow w 
                                LEFT JOIN workflowbase wb ON wb.workflowbaseid=w.workflowbaseid
                               </string>
        strSql += String.Format(" WHERE w.workflowid='{0}'", workfLowID)
        GetWorkFlowNameByWorkFLowID = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 根据超越单ID获取附件信息
    ''' create:Wangjh 20171124
    ''' </summary>
    ''' <param name="surpassBillInfoID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSurpassAccessories(ByVal surpassBillInfoID As String) As DataTable Implements uLMSCommonIBusiness.GetSurpassAccessories
        Dim strSql As String = " SELECT sbi.*,'<a href='''||'http://10.15.7.76/InSiteWebApplication/Temp/'||replace(sap.accessoriespath,'\','/')||''''||''''||' target=''_blank''' ||' style='''||'font-size: x-small;height:10px;text-align: center;color:Blue;'''||'>'|| SUBSTR(sap.accessoriespath,INSTR( sap.accessoriespath,'\')+1)||'</a>'  accessoriesname  FROM SurpassAccessoriesPath sap "
        strSql += " LEFT JOIN surpassbillinfo sbi ON sbi.surpassbillinfoid=sap.surpassbillinfoid"
        strSql += String.Format(" WHERE sap.surpassbillinfoid in ({0})", surpassBillInfoID)
        GetSurpassAccessories = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function
    ''' <summary>
    ''' 根据workflowstepid获取specname
    ''' create:Wangjh 20171127
    ''' </summary>
    ''' <param name="workflowStepID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSpecNameByWorkflowStepID(ByVal workflowStepID As String) As DataTable Implements uLMSCommonIBusiness.GetSpecNameByWorkflowStepID
        Dim strSql As String = <string>
                                  SELECT sb2.specname,ws.workflowstepname,s.specno FROM workflowstep ws 
                                    LEFT JOIN specbase sb ON sb.specbaseid=ws.specbaseid
                                    LEFT JOIN spec s ON s.specid=NVL(sb.revofrcdid,ws.specid)
                                    LEFT JOIN specbase sb2 ON sb2.specbaseid=s.specbaseid
                              </string>
        strSql += String.Format(" WHERE ws.workflowstepid='{0}'", workflowStepID)
        GetSpecNameByWorkflowStepID = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 获取批量类型的批次大批次号是否已存在 create tianFW 2017/11/2
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function IsExistTogetherFlag(ByVal value As String) As DataTable Implements uLMSCommonIBusiness.IsExistTogetherFlag
        Dim strsql As New StringBuilder
        strsql.AppendFormat("SELECT C.TOGETHERFLAG FROM CONTAINER C WHERE {0}", value)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 服务汇总表中是否有拆分的批次信息存在 create tianFW 2017年11月14日
    ''' </summary>
    ''' <param name="containerid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function IsContainerExistINContainerCurrent(ByVal containerid As String) As DataTable Implements uLMSCommonIBusiness.IsContainerExistINContainerCurrent
        Dim strsql As String = String.Format("SELECT C.* FROM CONTAINERCURRENTINFO C WHERE C.CONTAINERNAME='{0}'", containerid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 创建或插入导入数据的结果信息 create tianFW 2017年11月15日
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetImportInfo(ByVal tableName As String, ByVal para As Dictionary(Of Integer, Dictionary(Of String, String)), ByVal maxindex As Integer, ByVal list As Dictionary(Of Integer, String)) As Boolean Implements uLMSCommonIBusiness.GetImportInfo
        GetImportInfo = False
        Dim strsql As String = String.Format("SELECT COUNT(*) COUNT FROM user_tables WHERE table_name='{0}'", tableName.ToUpper())
        If DatabaseHelper.Query_ReturnDatTable(strsql).Rows(0)("COUNT") = 0 Then
            Dim strsql_ As New StringBuilder
            strsql_.AppendFormat("CREATE TABLE {0} (", tableName)
            For i As Integer = 0 To list.Count - 1
                If i = 0 Then
                    strsql_.AppendFormat(list(i) & " VARCHAR2(100)")
                Else
                    strsql_.AppendFormat("," & list(i) & " VARCHAR2(100)")
                End If
            Next
            strsql_.AppendLine(")")
            DatabaseHelper.ExecuteSql(strsql_.ToString())
            strsql_.Clear()
            For k As Integer = 1 To maxindex
                strsql_.AppendFormat("INSERT INTO {0} (", tableName)
                For i As Integer = 0 To list.Count - 1
                    If i = 0 Then
                        strsql_.AppendFormat("{0}", list(i))
                    Else
                        strsql_.AppendFormat(",{0}", list(i))
                    End If
                Next
                strsql_.AppendLine(") VALUES(")
                For i As Integer = 0 To list.Count - 1
                    If i = 0 Then
                        strsql_.AppendLine("'" & para(k)(list(i).ToString) & "'")
                    Else
                        strsql_.AppendLine(",'" & para(k)(list(i).ToString) & "'")
                    End If
                Next
                strsql_.AppendLine(")")
                DatabaseHelper.ExecuteSql(strsql_.ToString())
                strsql_.Clear()
            Next
        Else
            Dim strsql_1 As String = String.Format("DELETE FROM {0}", tableName)
            DatabaseHelper.ExecuteSql(strsql_1)
            Dim strsql_ As New StringBuilder
            For k As Integer = 1 To maxindex
                strsql_.AppendFormat("INSERT INTO {0} (", tableName)
                For i As Integer = 0 To list.Count - 1
                    If i = 0 Then
                        strsql_.AppendFormat("{0}", list(i))
                    Else
                        strsql_.AppendFormat(",{0}", list(i))
                    End If
                Next
                strsql_.AppendLine(") VALUES(")
                For i As Integer = 0 To list.Count - 1
                    If i = 0 Then
                        strsql_.AppendLine("'" & para(k)(list(i).ToString) & "'")
                    Else
                        strsql_.AppendLine(",'" & para(k)(list(i).ToString) & "'")
                    End If
                Next
                strsql_.AppendLine(")")
                DatabaseHelper.ExecuteSql(strsql_.ToString())
                strsql_.Clear()
            Next
        End If
        GetImportInfo = True
    End Function

    ''' <summary>
    ''' 删除表 create tianFW 2017年11月16日
    ''' </summary>
    ''' <param name="tablename"></param>
    ''' <remarks></remarks>
    Public Sub DeleteImportInfo(ByVal tablename As String) Implements uLMSCommonIBusiness.DeleteImportInfo
        DatabaseHelper.ExecuteSql(String.Format("DROP TABLE {0}", tablename))
    End Sub

    ''' <summary>
    ''' 获取工区中的班次信息 createtianFW 2017年11月22日(ZS) 
    ''' </summary>
    ''' <param name="workcenterID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetShiftInfoByWorkcenterID(ByVal workcenterID As String) As DataTable Implements uLMSCommonIBusiness.GetShiftInfoByWorkcenterID
        Dim strsql As New StringBuilder
        strsql.AppendFormat("SELECT S.SHIFTID,S.SHIFTNAME,S.FACTORYID,S.WORKCENTERID FROM SHIFT S WHERE S.WORKCENTERID='{0}'", workcenterID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据组Id获取工区和班 Modify by Yuxj20181213
    ''' </summary>
    ''' <param name="teamId"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetShiftAndWorkcenterByTeamid(ByVal teamId As String) As DataTable Implements uLMSCommonIBusiness.GetShiftAndWorkcenterByTeamid
        Dim strsql As New StringBuilder
        strsql.AppendFormat("SELECT t.teamid,t.teamname,s.shiftid,s.shiftname,w.workcenterid,w.workcentername FROM team t ")
        strsql.AppendLine("LEFT JOIN shift s ON t.shiftid=s.shiftid ")
        strsql.AppendLine("LEFT JOIN Workcenter w ON s.workcenterid=w.workcenterid ")
        strsql.AppendFormat("WHERE t.teamid='{0}' ", teamId)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据班次ID获取班组信息 create tianFW 2017年11月23日
    ''' </summary>
    ''' <param name="shiftID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTeamByShiftID(ByVal shiftID As String) As DataTable Implements uLMSCommonIBusiness.GetTeamByShiftID
        Dim strsql As String = String.Format("SELECT * FROM TEAM T WHERE T.SHIFTID='{0}'", shiftID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 根据工区ID获取班组信息 create YangJiang 20180614
    ''' </summary>
    ''' <param name="WorkcenterID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTeamByWorkcenterID(ByVal WorkcenterID As String) As DataTable Implements uLMSCommonIBusiness.GetTeamByWorkcenterID
        Dim strsql As String = String.Format("SELECT * FROM TEAM T WHERE t.shiftid IS NULL AND T.workcenterid='{0}'", WorkcenterID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 根据工序WorkflowStepIDs获取工步信息 create tianFW 2017年11月29日
    ''' 增加工步初装 检装工时列
    ''' </summary>
    ''' <param name="workflowStepIDs">工序IDs</param>
    ''' <param name="containerid">批次id</param>
    ''' <param name="workerID">工人id</param>
    ''' <param name="type">查询类型 string "1"-未派工 "2"-已派工</param>
    ''' <returns></returns>
    ''' <remarks>DECODE(B.CONTAINERSTEPDISPATCHID,NULL,'未派','已派') DispatchStatus add YangJiang 20180718</remarks>
    Public Function GetStepInfo_InfoByWorkflowStepIDs(ByVal workflowStepIDs As String, ByVal containerid As String, ByVal workerID As String, ByVal type As String,
                                                      Optional ByVal isZs As Boolean = False
                                                      ) As DataTable Implements uLMSCommonIBusiness.GetStepInfo_InfoByWorkflowStepIDs
        Dim strsql As New StringBuilder

        strsql.AppendLine("select *  from (")

        strsql.AppendLine("SELECT a.durationperunit,a.durationperunit2, ws.sequence,a.STEPSEQ,WS.WORKFLOWSTEPID,WS.WORKFLOWSTEPNAME,A.STEPINFONAME,A.STEPINFOID,A.STEPNO,A.description STEPINFODESC,A.SPECTYPENAME,")
        strsql.AppendLine("T.TEAMNAME,EM.FULLNAME DISPATCHFULLNAME,B.PLANNEDSTARTDATE,B.PLANNEDFINISHDATE,B.CONTAINERSTEPDISPATCHID,DECODE(B.CONTAINERSTEPDISPATCHID,NULL,'未派','已派') DispatchStatus")
        strsql.AppendLine("FROM WORKFLOWSTEP WS")
        strsql.AppendLine("LEFT JOIN(")
        strsql.AppendLine("SELECT SOB.STEPINFONAME,SO.STEPINFOID,SO.REVISION,SO.SPECID,SO.STEPSEQ,SO.STEPNO,ST.SPECTYPENAME,SO.WORKFLOWSTEPID,so.description,nvl(SO.durationperunit,0) durationperunit, nvl(SO.durationperunit2,0) durationperunit2 FROM STEPINFOBASE SOB")
        strsql.AppendLine("LEFT JOIN STEPINFO SO ON SO.STEPINFOBASEID = SOB.STEPINFOBASEID")
        strsql.AppendLine("LEFT JOIN SPECTYPE ST ON ST.SPECTYPEID = SO.SPECTYPEID")
        strsql.AppendLine(") A ON A.WORKFLOWSTEPID = WS.WORKFLOWSTEPID")
        strsql.AppendLine("LEFT JOIN (SELECT CSD.WORKFLOWSTEPID,CSD.STEPINFOID,CSD.TEAMID,CSD.EMPLOYEEID,CSD.PLANNEDSTARTDATE,CSD.PLANNEDFINISHDATE, ")
        strsql.AppendLine(" CSD.CONTAINERSTEPDISPATCHID FROM CONTAINERSTEPDISPATCH CSD")
        If Not String.IsNullOrWhiteSpace(workerID) Then
            If isZs Then
                strsql.AppendLine("LEFT JOIN CONTAINERSTEPDISPATCHDETAIL_ZS CSDD ON CSDD.CONTAINERSTEPDISPATCHID = CSD.CONTAINERSTEPDISPATCHID")
            Else
                strsql.AppendLine("LEFT JOIN CONTAINERSTEPDISPATCHDETAIL CSDD ON CSDD.CONTAINERSTEPDISPATCHID = CSD.CONTAINERSTEPDISPATCHID")
            End If

            strsql.AppendLine("LEFT JOIN CONTAINERSTEPWORKREPORT CSW ON CSW.CONTAINERSTEPDISPATCHID = CSD.CONTAINERSTEPDISPATCHID AND CSW.ISUSE = 0")
        End If
        strsql.AppendLine("WHERE CSD.ISUSE=0")
        If Not String.IsNullOrWhiteSpace(workerID) Then
            strsql.AppendFormat(" AND CSW.CONTAINERSTEPWORKREPORTID IS NULL AND CSDD.WORKERID='{0}'", workerID)
        End If
        strsql.AppendFormat(" AND CSD.CONTAINERID='{0}') B ON B.WORKFLOWSTEPID = WS.WORKFLOWSTEPID ", containerid)
        strsql.AppendLine("LEFT JOIN TEAM T ON T.TEAMID = B.TEAMID")
        strsql.AppendLine("LEFT JOIN EMPLOYEE EM ON EM.EMPLOYEEID = B.EMPLOYEEID")
        strsql.AppendFormat(" WHERE  a.STEPINFOID IS  NULL and ({0}) ", workflowStepIDs)
        'strsql.AppendLine("AND ((B.STEPINFOID IS NOT NULL AND B.STEPINFOID = A.STEPINFOID) OR B.STEPINFOID IS NULL)")
        If type = "1" Then
            strsql.AppendLine(" AND B.CONTAINERSTEPDISPATCHID IS NULL") '未派工
        ElseIf type = "2" Then
            strsql.AppendLine(" AND B.CONTAINERSTEPDISPATCHID IS NOT NULL") '已派工
        End If

        strsql.AppendLine("union")

        strsql.AppendLine("SELECT a.durationperunit,a.durationperunit2,  ws.sequence,a.STEPSEQ,WS.WORKFLOWSTEPID,WS.WORKFLOWSTEPNAME,A.STEPINFONAME,A.STEPINFOID,A.STEPNO,A.description STEPINFODESC,A.SPECTYPENAME,")
        strsql.AppendLine("T.TEAMNAME,EM.FULLNAME DISPATCHFULLNAME,B.PLANNEDSTARTDATE,B.PLANNEDFINISHDATE,B.CONTAINERSTEPDISPATCHID,DECODE(B.CONTAINERSTEPDISPATCHID,NULL,'未派','已派') DispatchStatus")
        strsql.AppendLine("FROM WORKFLOWSTEP WS")
        strsql.AppendLine("LEFT JOIN(")
        strsql.AppendLine("SELECT SOB.STEPINFONAME,SO.STEPINFOID,SO.REVISION,SO.SPECID,SO.STEPSEQ,SO.STEPNO,ST.SPECTYPENAME,SO.WORKFLOWSTEPID,so.description,nvl(SO.durationperunit,0) durationperunit, nvl(SO.durationperunit2,0) durationperunit2 FROM STEPINFOBASE SOB")
        strsql.AppendLine("LEFT JOIN STEPINFO SO ON SO.STEPINFOBASEID = SOB.STEPINFOBASEID")
        strsql.AppendLine("LEFT JOIN SPECTYPE ST ON ST.SPECTYPEID = SO.SPECTYPEID")
        strsql.AppendLine(") A ON A.WORKFLOWSTEPID = WS.WORKFLOWSTEPID")
        strsql.AppendLine("LEFT JOIN (SELECT CSD.WORKFLOWSTEPID,CSD.STEPINFOID,CSD.TEAMID,CSD.EMPLOYEEID,CSD.PLANNEDSTARTDATE,CSD.PLANNEDFINISHDATE, ")
        strsql.AppendLine(" CSD.CONTAINERSTEPDISPATCHID FROM CONTAINERSTEPDISPATCH CSD")
        If Not String.IsNullOrWhiteSpace(workerID) Then
            If isZs Then
                strsql.AppendLine("LEFT JOIN CONTAINERSTEPDISPATCHDETAIL_ZS CSDD ON CSDD.CONTAINERSTEPDISPATCHID = CSD.CONTAINERSTEPDISPATCHID")
            Else
                strsql.AppendLine("LEFT JOIN CONTAINERSTEPDISPATCHDETAIL CSDD ON CSDD.CONTAINERSTEPDISPATCHID = CSD.CONTAINERSTEPDISPATCHID")
            End If

            strsql.AppendLine("LEFT JOIN CONTAINERSTEPWORKREPORT CSW ON CSW.CONTAINERSTEPDISPATCHID = CSD.CONTAINERSTEPDISPATCHID AND CSW.ISUSE = 0")
        End If
        strsql.AppendLine("WHERE CSD.ISUSE=0")
        If Not String.IsNullOrWhiteSpace(workerID) Then
            strsql.AppendFormat(" AND CSW.CONTAINERSTEPWORKREPORTID IS NULL AND CSDD.WORKERID='{0}'", workerID)
        End If
        strsql.AppendFormat(" AND CSD.CONTAINERID='{0}') B ON B.WORKFLOWSTEPID = WS.WORKFLOWSTEPID AND a.STEPINFOID=b.STEPINFOID ", containerid)
        strsql.AppendLine("LEFT JOIN TEAM T ON T.TEAMID = B.TEAMID")
        strsql.AppendLine("LEFT JOIN EMPLOYEE EM ON EM.EMPLOYEEID = B.EMPLOYEEID")
        strsql.AppendFormat(" WHERE  a.STEPINFOID IS not NULL and ({0}) ", workflowStepIDs)
        'strsql.AppendLine("AND ((B.STEPINFOID IS NOT NULL AND B.STEPINFOID = A.STEPINFOID) OR B.STEPINFOID IS NULL)")
        If type = "1" Then
            strsql.AppendLine(" AND B.CONTAINERSTEPDISPATCHID IS NULL") '未派工
        ElseIf type = "2" Then
            strsql.AppendLine(" AND B.CONTAINERSTEPDISPATCHID IS NOT NULL") '已派工
        End If



        strsql.AppendLine(") ORDER BY SEQUENCE,STEPSEQ")
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    Public Function GetBomByProduct(ByVal productname As String, ByVal revision As String) As DataTable Implements uLMSCommonIBusiness.GetBomByProduct

        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT pb.productname,p.productrevision,b1.bomid,decode(bb1.bomname,'','',bb1.bomname||':'||b1.bomrevision) bomname  FROM product p ")
        strSql.AppendLine("LEFT JOIN productbase pb ON pb.productbaseid=p.productbaseid ")
        strSql.AppendLine("LEFT JOIN bom b ON b.bomid=p.bomid ")
        strSql.AppendLine("LEFT JOIN bombase bb ON bb.bombaseid=p.bombaseid ")
        strSql.AppendLine("LEFT JOIN bom b1 ON b1.bomid=NVL(bb.revofrcdid,b.bomid) ")
        strSql.AppendLine("LEFT JOIN bombase bb1 ON bb1.bombaseid=b1.bombaseid ")
        strSql.AppendFormat("WHERE pb.productname='{0}'  AND p.productrevision='{1}'", productname, revision)

        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql.ToString)
        Return DT
    End Function

    ''' <summary>
    ''' 获取工艺下面的bom信息 create tianFW 2017年12月4日
    ''' </summary>
    ''' <param name="workflowID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetBomByWorkflowID(ByVal workflowID As String) As DataTable Implements uLMSCommonIBusiness.GetBomByWorkflowID
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT B.BOMID,B.WIPMSGDEFMGRID,B.BOMBASEID,B.WORKFLOWID,B.PRODUCTID,DECODE(BB.BOMNAME,'','',BB.BOMNAME||':'||B.BOMREVISION) BOMNAME")
        strsql.AppendLine(",DECODE(BT.BILLTYPENAME,'消耗件','BOM','大小件目录','PRODUCTMATERIAL','BOM') BILLTYPENAME")
        strsql.AppendLine("FROM BOM B")
        strsql.AppendLine("LEFT JOIN BOMBASE BB ON BB.BOMBASEID = B.BOMBASEID")
        strsql.AppendLine("LEFT JOIN BILLTYPE BT ON BT.BILLTYPEID = B.BILLTYPEID")
        strsql.AppendFormat("WHERE B.WORKFLOWID ='{0}'", workflowID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取件号下面的bom信息 create tianFW 2017年12月5日
    ''' </summary>
    ''' <param name="ProductID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetBomByProductID(ByVal ProductID As String) As DataTable Implements uLMSCommonIBusiness.GetBomByProductID
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT B.BOMID,B.WIPMSGDEFMGRID,B.BOMBASEID,B.WORKFLOWID,B.PRODUCTID,DECODE(BB.BOMNAME,'','',BB.BOMNAME||':'||B.BOMREVISION) BOMNAME")
        strsql.AppendLine("FROM BOM B")
        strsql.AppendLine("LEFT JOIN BOMBASE BB ON BB.BOMBASEID = B.BOMBASEID")
        strsql.AppendFormat("WHERE B.PRODUCTID ='{0}'", ProductID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 模糊查询出批次的信息
    ''' create:Wangjh 20171212
    ''' </summary>
    ''' <param name="strContainerName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetContainerByLikeContainerName(ByVal strContainerName As String) As DataTable Implements uLMSCommonIBusiness.GetContainerByLikeContainerName
        Dim strSql As String = String.Format("SELECT C.CONTAINERID FROM container c WHERE c.containername LIKE '{0}%'", strContainerName)

        GetContainerByLikeContainerName = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 根据工艺ID获取工艺的最后一道序
    ''' create:Wangjh 20171221
    ''' </summary>
    ''' <param name="workFlowID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetLastWorkFlowStepByWorkFlowID(ByVal workFlowID As String) As DataTable Implements uLMSCommonIBusiness.GetLastWorkFlowStepByWorkFlowID
        Dim strSql As String = "SELECT ws.workflowstepid,ws.workflowstepname,ws.sequence FROM workflowstep ws " &
                            " WHERE  (ws.islaststep=1 OR ws.defaultpathid IS NULL)"
        strSql += String.Format(" AND ws.workflowid='{0}'", workFlowID)
        GetLastWorkFlowStepByWorkFlowID = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 获取工序的子工艺信息
    ''' create：Wangjh 20171221
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSubWorkFlowInfoByStep(ByVal para As System.Collections.Generic.Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetSubWorkFlowInfoByStep
        Dim strSql As String = <string>
                                   SELECT wb2.workflowname,w.workflowrevision,ws.steptype,w.workflowid FROM Workflowstep ws 
                                    LEFT JOIN Workflowbase wb ON wb.workflowbaseid=ws.subworkflowbaseid
                                    LEFT JOIN workflow w ON w.workflowid=NVL(wb.revofrcdid,ws.subworkflowid)
                                    LEFT JOIN WORKFLOWBASE WB2 on WB2.workflowbaseid=W.workflowbaseid
                                    where 1=1
                               </string>
        If para.ContainsKey("WorkFlowID") Then
            strSql += String.Format(" AND WS.WorkFLowID='{0}'", para("WorkFlowID"))
        End If
        If para.ContainsKey("Sequence") Then
            strSql += String.Format(" AND WS.Sequence={0}", para("Sequence"))
        End If
        If para.ContainsKey("WorkFlowStepID") Then
            strSql += String.Format(" AND WS.WorkFlowStepID='{0}'", para("WorkFlowStepID"))
        End If
        GetSubWorkFlowInfoByStep = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 获取产品BOM明细
    ''' </summary>
    ''' <param name="productID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetBomDetailByProductID(ByVal productID As String) As DataTable Implements uLMSCommonIBusiness.GetBomDetailByProductID

        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT PB1.PRODUCTNAME,P1.PRODUCTREVISION,P1.PRODUCTID , WFB1.WORKFLOWNAME,")
        strSql.AppendLine("P1.DESCRIPTION PRODUCTDESCRIPTION,PMLI.QTYREQUIRED,WF.WORKFLOWREVISION,WF.WORKFLOWID,P.PRODUCTID BOMPRODUCTID")
        strSql.AppendLine("FROM PRODUCT P ")
        strSql.AppendLine("LEFT JOIN BOMBASE BB ON BB.BOMBASEID = P.BOMBASEID")
        strSql.AppendLine("LEFT JOIN BOM B ON B.BOMID = NVL(BB.REVOFRCDID, P.BOMID)")
        strSql.AppendLine("LEFT JOIN PRODUCTMATERIALLISTITEM PMLI  ON B.BOMID = PMLI.BOMID")
        strSql.AppendLine("LEFT JOIN PRODUCTBASE PB ON PMLI.PRODUCTBASEID = PB.PRODUCTBASEID")
        strSql.AppendLine("LEFT JOIN PRODUCT P1 ON P1.PRODUCTID = NVL(PB.REVOFRCDID, PMLI.PRODUCTID)")
        strSql.AppendLine("LEFT JOIN PRODUCTBASE PB1 ON PB1.PRODUCTBASEID = P1.PRODUCTBASEID")
        strSql.AppendLine("LEFT JOIN WORKFLOWBASE WFB  ON WFB.WORKFLOWBASEID = P1.WORKFLOWBASEID")
        strSql.AppendLine("LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = NVL(WFB.REVOFRCDID, P1.WORKFLOWID)")
        strSql.AppendLine("LEFT JOIN WORKFLOWBASE WFB1 ON WFB1.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        strSql.AppendFormat("WHERE P.PRODUCTID ='{0}'", productID)

        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql.ToString)
        Return DT
    End Function

    ''' <summary>
    ''' 获取单位信息 create tianFW 2017年12月13日
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetUom() As DataTable Implements uLMSCommonIBusiness.GetUom
        Dim strsql As String = "SELECT U.UOMID,U.UOMNAME,U.DESCRIPTION FROM UOM U"
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 获取工艺上的机型 create tianFW 2017年12月19日
    ''' </summary>
    ''' <param name="workflowid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkflowPorductFamily(ByVal workflowid As String) As DataTable Implements uLMSCommonIBusiness.GetWorkflowPorductFamily
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT WFFL.PRODUCTFAMILYLISTID,PF.FAMILYTYPE,PF.PRODUCTFAMILYNAME")
        strsql.AppendLine("FROM WORKFLOWPRODUCTFAMILYLIST WFFL")
        strsql.AppendLine("LEFT JOIN PRODUCTFAMILY PF ON PF.PRODUCTFAMILYID = WFFL.PRODUCTFAMILYLISTID")
        strsql.AppendFormat(" WHERE WFFL.WORKFLOWID = '{0}'", workflowid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据ContainerID获取汇总表中的批次数量，报工数量，报废数量 createtianFW 
    ''' </summary>
    ''' <param name="containerid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetCurrentInfoByContainerID(ByVal containerid As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetCurrentInfoByContainerID
        Dim strsql As String = String.Format("SELECT C.* FROM CONTAINERCURRENTINFO C WHERE C.CONTAINERID = '{0}'", containerid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 通过工区ID查询工区信息 create tianFW 2018年1月17日
    ''' </summary>
    ''' <param name="WorkCenterID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkCenterInfoByWorkCenterID(ByVal WorkCenterID As String) As DataTable Implements uLMSCommonIBusiness.GetWorkCenterInfoByWorkCenterID
        Dim strsql As String = String.Format("SELECT * FROM WORKCENTER WC WHERE WC.WORKCENTERID='{0}'", WorkCenterID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function


    ''' <summary>
    ''' 通过班组ID查询班组信息 create tianFW 2018年1月17日
    ''' </summary>
    ''' <param name="TeamID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetTeamInfoByTeamID(ByVal TeamID As String) As DataTable Implements uLMSCommonIBusiness.GetTeamInfoByTeamID
        Dim strsql As String = String.Format("SELECT * FROM TEAM T WHERE T.TEAMID='{0}'", TeamID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' add by yuxj 20171228 装试项目获取工步
    ''' 工步描述显示加上工步号，增加排序20230401
    ''' </summary>
    ''' <param name="stepid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetStepinfoDt(ByVal stepid As String) As DataTable Implements uLMSCommonIBusiness.GetStepinfoDt
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT SOB.STEPINFONAME,SO.STEPINFOID,SO.REVISION,SO.SPECID,SO.STEPSEQ,SO.STEPNO,ST.SPECTYPENAME,ws.workflowstepname,SO.WORKFLOWSTEPID,so.StepNO||'-'||so.description stepinfodesc")
        sb.AppendLine(",ct.lastchangedate")
        sb.AppendLine("FROM STEPINFOBASE SOB")
        sb.AppendLine("LEFT JOIN STEPINFO SO ON SO.STEPINFOID = SOB.REVOFRCDID  ")
        sb.AppendLine(" left join workflowstep ws on ws.WORKFLOWSTEPID=so.WORKFLOWSTEPID ")
        sb.AppendLine("LEFT JOIN SPECTYPE ST ON ST.SPECTYPEID = SO.SPECTYPEID ")
        sb.AppendLine("LEFT JOIN Changestatus ct ON ct.parentid =  SO.STEPINFOID")
        sb.AppendFormat("where so.workflowstepid in ('{0}') ", stepid.Replace(",", "','"))
        sb.AppendLine(" order by ws.sequence,SO.STEPNO,SO.stepseq asc ")
        Return DatabaseHelper.Query_ReturnDatTable(sb.ToString)
    End Function

    ''' <summary>
    ''' 获取工序是否是固定检验序 add by tianFW 2018年2月5日
    ''' </summary>
    ''' <param name="stepid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetStepLastCheck(ByVal stepid As String) As DataTable Implements uLMSCommonIBusiness.GetStepLastCheck
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT S.LASTCHECK FROM  WORKFLOWSTEP WS")
        strsql.AppendLine("LEFT JOIN SPECBASE SB ON SB.SPECBASEID = WS.SPECBASEID")
        strsql.AppendLine("LEFT JOIN SPEC S ON S.SPECID = NVL(SB.REVOFRCDID,WS.SPECID)")
        strsql.AppendFormat(" WHERE WS.WORKFLOWSTEPID='{0}'", stepid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 根据厂别获取Bom明细 Add by Yuxj20180129
    ''' </summary>
    ''' <param name="productID"></param>
    ''' <param name="factoryID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetBomDetailByProductID(ByVal productID As String, ByVal factoryID As String) As DataTable Implements uLMSCommonIBusiness.GetBomDetailByProductID

        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT PB1.PRODUCTNAME,P1.PRODUCTREVISION,P1.PRODUCTID , WFB1.WORKFLOWNAME,")
        strSql.AppendLine("P1.DESCRIPTION PRODUCTDESCRIPTION,PMLI.QTYREQUIRED,WF.WORKFLOWREVISION,WF.WORKFLOWID,P.PRODUCTID BOMPRODUCTID,wf.factoryid ")
        strSql.AppendLine("FROM PRODUCT P ")
        strSql.AppendLine("LEFT JOIN BOMBASE BB ON BB.BOMBASEID = P.BOMBASEID")
        strSql.AppendLine("LEFT JOIN BOM B ON B.BOMID = NVL(BB.REVOFRCDID, P.BOMID)")
        strSql.AppendLine("LEFT JOIN PRODUCTMATERIALLISTITEM PMLI  ON B.BOMID = PMLI.BOMID")
        strSql.AppendLine("LEFT JOIN PRODUCTBASE PB ON PMLI.PRODUCTBASEID = PB.PRODUCTBASEID")
        strSql.AppendLine("LEFT JOIN PRODUCT P1 ON P1.PRODUCTID = NVL(PB.REVOFRCDID, PMLI.PRODUCTID)")
        'Modify by Yuxj20180129 增加厂别信息
        strSql.AppendLine("LEFT JOIN factory f ON p1.factoryid=f.factoryid")

        strSql.AppendLine("LEFT JOIN PRODUCTBASE PB1 ON PB1.PRODUCTBASEID = P1.PRODUCTBASEID")
        strSql.AppendLine("LEFT JOIN WORKFLOWBASE WFB  ON WFB.WORKFLOWBASEID = P1.WORKFLOWBASEID")
        strSql.AppendLine("LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = NVL(WFB.REVOFRCDID, P1.WORKFLOWID)")
        strSql.AppendLine("LEFT JOIN WORKFLOWBASE WFB1 ON WFB1.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        strSql.AppendFormat("WHERE P.PRODUCTID ='{0}'", productID)

        'Modify by Yuxj20180129
        strSql.AppendFormat("and f.factoryid ='{0}'", factoryID)

        Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql.ToString)
        Return DT
    End Function

    ''' <summary>
    ''' 获取员工所属工区create by tianFW 2018年2月7日
    ''' </summary>
    ''' <param name="EmployeeID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetEmployeeWorkCenterInfo(ByVal EmployeeID As String) As DataTable Implements uLMSCommonIBusiness.GetEmployeeWorkCenterInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT WC.* FROM EMPLOYEE E")
        strsql.AppendLine("LEFT JOIN  SESSIONVALUES SV ON SV.SESSIONVALUESID = E.SESSIONVALUESID")
        strsql.AppendLine("LEFT JOIN WORKCENTER WC ON WC.WORKCENTERID = SV.WORKCENTERID")
        strsql.AppendFormat(" WHERE E.EMPLOYEEID = '{0}' ", EmployeeID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 移动批次到下一序并且进入固定外委或固定转工 create tianFW 2018年4月10日
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function MoveToNextStepAndFixCommissionOrFixShip(ByVal para As Dictionary(Of String, Object), ByRef message As String) As Boolean Implements uLMSCommonIBusiness.MoveToNextStepAndFixCommissionOrFixShip
        MoveToNextStepAndFixCommissionOrFixShip = False
        Dim containerID As String = para("ContainerID")
        Dim sequence As Integer = para("Sequence")
        Dim workflowID As String = para("WorkflowID")
        Dim isexistcount = 0
        Dim isSubWorkflow = False
        Dim OriginalFactoryID As String = para("OriginalFactoryID")
        Dim isShip As Boolean = para("IsShip")
        '1.如果isexistcount=0，则说明返回的是批次下一序就是当前工艺当前序的下一序；返回的是批次下一序即当前序下一序的工序名称、序号和ID。
        '2.如果isexistcount>0 且返回长度>2，则说明下一序的工艺路线改变了；传回批次下一序的工序名称、ID、序号以及工艺名称、版本、ID和工艺承制分厂。
        '3.如果isexistcount>0 且长度=2，则说明工艺路线没变，但是批次下一序不是工序的下一序，返回批次下一序的工序名称、序号和ID。
        '注：分批时，传入的是父批次的ID，检验父批次有没有记录存在
        Dim GetNextStepNoCheckInfo_ As String = GetNextStepNoCheckInfo(containerID, sequence, workflowID, isexistcount, isSubWorkflow, OriginalFactoryID, isShip)
        Dim serverInfo As New ServerHostInfo
        serverInfo.UserName = para("UserName")
        serverInfo.Password = para("Password")
        Dim excResult = False '移动是否成功
        Dim uLMSContainerBus_Obj As New uLMSContainerBusiness
        For i As Integer = 0 To isexistcount
            If i < isexistcount Then
                excResult = uLMSContainerBus_Obj.ContainerMoveStd(serverInfo, para("ContainerName"), para("EmployeeName"), "BackoutMove", message) 'BackoutMove 撤销移动
            Else
                excResult = uLMSContainerBus_Obj.ContainerMoveStd(serverInfo, para("ContainerName"), para("EmployeeName"), message)
            End If
            If excResult = False Then
                Exit Function
            End If
        Next
        If isShip Then
            message = ""
            MoveToNextStepAndFixCommissionOrFixShip = True
            Exit Function
        End If
        Dim strValueStepIDs = GetNextStepNoCheckInfo_.Split(",")
        Dim strValueStepID = strValueStepIDs(1) '使用GetNextStepNoCheckInfo返回的获得的工序ID
        '转工判断下一序是否需要固定外委或转工
        'Dim factoryid_ As String = "" '批次下一序工艺的所属分厂ID
        'If strValueStepIDs.Length = 2 Then '批次当前分厂就是工艺所属分厂
        '    factoryid_ = OriginalFactoryID
        'Else '工艺所属分厂
        '    factoryid_ = strValueStepIDs(4)
        'End If
        ' LogHelp.SetConfig()
        'LogHelp.WriteOrcale("自动转工检测" + "@^" + "开始处理自动转工或者外委" + "@^" + para("ContainerName") + "@^" + Convert.ToString(Guid.NewGuid()) + "@^" + para("ContainerID")) 'add:Wangjh 写入数据库   
        If GetControlCodeByWorkflowStepID(strValueStepID) = "LY05" Then
            FixedCommission(workflowID, OriginalFactoryID, para, sequence, strValueStepID)
            message = ""
            MoveToNextStepAndFixCommissionOrFixShip = True
            Exit Function
            'Else'update:Wangjh 20180515 自动转工转移到后台服务
            '    LogHelp.WriteOrcale("自动转工检测" + "@^" + "开始检测处理自动转工" + "@^" + para("ContainerName") + "@^" + Convert.ToString(Guid.NewGuid()) + "@^" + para("ContainerID")) 'add:Wangjh 写入数据库   
            '    Dim para_ As New Dictionary(Of String, String)
            '    para_("WorkflowID") = para("WorkflowID") '批次当前所在工艺ID
            '    '批次所属分厂ID （用来判断批次下一序是子工艺，子工艺是否是固定转工）
            '    '因为分批只能本分厂拆分，所以也等价于para_("FactoryID")=m_UserInfo.FactoryID
            '    para_("FactoryID") = OriginalFactoryID
            '    Dim factoryid = GetFixShipWorkflowStepInfo(para_, containerID, isSubWorkflow, workflowID, sequence, strValueStepID) '固定转工
            '    'factoryid = "" 的情况，这种情况下取上面方法处理传回的工序信息
            '    '1.批次当前工艺是父工艺, 返回的是子工艺且子工艺不是固定转工
            '    '2.批次当前工艺是子工艺，返回的是其他子工艺且该子工艺不是固定转工序
            '    '3.批次当前工艺是子工艺，返回的是子工艺的正常序，也不是固定转工
            '    If factoryid = "" Then
            '        message = ""
            '        MoveToNextStepAndFixCommissionOrFixShip = True
            '        Exit Function
            '    End If
            '    Dim newpara As New Dictionary(Of String, String)
            '    newpara("EmployeeID") = para("EmployeeID")
            '    newpara("FactoryID") = factoryid
            '    If para.ContainsKey("NewContainerID") Then
            '        newpara("ContainerID") = para("NewContainerID")
            '    Else
            '        newpara("ContainerID") = containerID
            '    End If
            '    newpara("WorkflowID") = workflowID
            '    newpara("Sequence") = sequence
            '    newpara("WorkFlowStepID") = strValueStepID
            '    newpara("UserInfoFactory") = para("FactoryID")
            '    Dim m_ContainerShip = New uLMSContainerShipBusiness()
            '    If Not m_ContainerShip.FixedContainerShip(newpara, New uLMSCommonBusiness) Then '固定转工
            '        MoveToNextStepAndFixCommissionOrFixShip = False
            '        message = "固定转工失败"
            '        Exit Function
            '    Else
            '        MoveToNextStepAndFixCommissionOrFixShip = True
            '        message = ""
            '        Exit Function
            '    End If
        End If
        message = ""
        MoveToNextStepAndFixCommissionOrFixShip = True
    End Function


    ''' <summary>
    ''' 工序在所属工艺上是否是固定外委 add tianFW 2018年4月10日
    ''' </summary>
    ''' <param name="WorkflowID"></param>
    ''' <param name="factoryid"></param>
    ''' <param name="para"></param>
    ''' <param name="sequence"></param>
    ''' <param name="WorkFlowStepID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function FixedCommission(ByVal WorkflowID As String, ByVal factoryid As String, ByVal para As Dictionary(Of String, Object), ByVal sequence As Integer, ByVal WorkFlowStepID As String) As Boolean
        FixedCommission = False
        Dim newpara As New Dictionary(Of String, String)
        newpara.Add("WorkflowID", WorkflowID)
        newpara.Add("Sequence", sequence)
        newpara.Add("WorkflowStepID", WorkFlowStepID)
        newpara.Add("FactoryID", factoryid)
        newpara.Add("EmployeeID", "")
        newpara.Add("OutQty", para("Qty"))
        If para.ContainsKey("NewContainerID") Then
            newpara.Add("ContainerID", para("NewContainerID"))
        Else
            newpara.Add("ContainerID", para("ContainerID"))
        End If
        newpara.Add("ContainerName", para("ContainerName"))
        Dim m_Commission As New uLMSCommissioningBusiness
        m_Commission.AddFixedCommissionInfo(newpara)
        Return True
    End Function

    ''' <summary>
    ''' 获取没有检验记录的下一序 create tianFW 2018年3月5日
    ''' </summary>
    ''' <param name="containerid">当前批次id</param>
    ''' <param name="workflowid">当前工艺id</param>
    ''' <param name="Sequence">当前序序号</param>
    ''' <param name="isexistcount">后面序存在检验记录、转工、外委记录的次数</param>
    ''' <param name="isSubWorkflow">当前工艺是否子工艺</param>
    ''' <param name="factoryid" >批次所属分厂ID</param>\
    ''' <param name="isShip" >批次是否转工已接收</param>
    ''' <returns>符合条件的下一序的名称和ID以及此序的工艺信息</returns>
    ''' <remarks>1.如果isexistcount=0，则说明返回的是批次下一序就是当前工艺当前序的下一序；返回的是批次下一序及当前序下一序的工序名称、序号和ID
    ''' 2.如果isexistcount=0 且返回的值拆分后长度>2，则说明下一序的工艺改变了；
    ''' 传回了批次下一序的工序名称、ID、序号以及工艺名称、版本和ID和子工艺承制分厂,移动isexistcount+1次后到达该序；
    ''' 3.如果长度=2，则说明工艺路线没变，但是批次下一序不是工序的下一序，移动isexistcount+1之后才能到达该序，返回批次下一序的工序名称、序号和ID</remarks>
    Function GetNextStepNoCheckInfo(ByVal containerid As String, ByRef Sequence As Integer, ByRef workflowid As String, ByRef isexistcount As Integer, ByRef isSubWorkflow As Boolean, ByVal factoryid As String, ByVal isShip As Boolean) As String Implements uLMSCommonIBusiness.GetNextStepNoCheckInfo
        GetNextStepNoCheckInfo = ""
        Dim father_workflow_dt As DataTable = GetFatherWorkflowInfo(containerid, workflowid)
        If father_workflow_dt.Rows.Count = 0 Then '批次当前工艺是父工艺路线
            isSubWorkflow = False
            '获取当前工艺的工序详细信息
            Dim para As New Dictionary(Of String, String)
            para("WorkflowID") = workflowid
            para.Add("NotChildWorkflow", "NotChildWorkflow") 'add:Wangjh 过滤掉子工艺序 20180830
            Dim dt As DataTable = GetWorkFlowSetpsDetailByWorkflowID(para)
            '获取下一序信息
            For Each dr As DataRow In dt.Rows
                If Integer.Parse(dr("SEQUENCE").ToString()) >= Sequence + 1 Then '当前序之后的序
                    If dr("WFSTYPE").ToString() = "Spec" Then '正常序
                        If Not GetFinishCheckInfoOrStepCheckInfo(containerid, dr("WORKFLOWSTEPID"), dr("SEQUENCE"), workflowid, isShip) Then
                            isexistcount += 1
                            Continue For
                        Else
                            GetNextStepNoCheckInfo = dr("WORKFLOWSTEPNAME").ToString() & "," & dr("WORKFLOWSTEPID").ToString() '返回下一序的工序信息
                            Sequence = Integer.Parse(dr("SEQUENCE").ToString())
                            Exit Function
                        End If
                    Else '子工艺
                        Dim dt_ As DataTable = GetWorkFlowSetpsByWorkflowID(dr("WORKFLOWID").ToString()) '子工艺工序列表
                        '获取子工艺工序是否有转工记录
                        '如果有则直接跳过该子工艺工序
                        If Not GetFinishCheckInfoOrStepCheckInfo(containerid, dr("WORKFLOWSTEPID"), dr("SEQUENCE"), workflowid, isShip) Then
                            isexistcount += dt_.Rows.Count
                            Continue For
                        End If
                        '如果没有,则判断该子工艺工序是不是固定转工工序
                        '是固定转工工序，则直接跳出程序,下一序就是子工艺的第一序
                        If Not dr.IsNull("FACTORYID") Then
                            If dr("FACTORYID") <> factoryid Then
                                GetNextStepNoCheckInfo = dt_.Rows(0)("WORKFLOWSTEPNAME") & "," & dt_.Rows(0)("WORKFLOWSTEPID") & "," &
                                    dr("WORKFLOWNAME") & "," & dr("WORKFLOWREVISION") & "," & dr("FACTORYID")
                                Sequence = Integer.Parse(dt_.Rows(0)("SEQUENCE"))
                                workflowid = dr("WORKFLOWID")
                                Exit Function
                            End If
                        End If
                        '不是固定转工工序，再进入子工艺工序循环查看工序否存在外委、转工或检验记录，如果存在外委、转工或检验记录，则直接跳出程序
                        For Each dr_ As DataRow In dt_.Rows
                            If Not GetFinishCheckInfoOrStepCheckInfo(containerid, dr_("WORKFLOWSTEPID"), dr_("SEQUENCE"), dr("WORKFLOWID"), isShip) Then
                                isexistcount += 1 '子工艺工序是按正常工序处理的，即不是子工艺工序
                                Continue For
                            Else
                                '子工艺则返回子工艺的workflowid以及子工艺中没有检验记录的工序信息,以及工序对应的工艺名称版本
                                '工艺名称和版本以及ID存在dt的行dr中
                                GetNextStepNoCheckInfo = dr_("WORKFLOWSTEPNAME") & "," & dr_("WORKFLOWSTEPID") & "," &
                                    dr("WORKFLOWNAME") & "," & dr("WORKFLOWREVISION") & "," & dr("FACTORYID")
                                Sequence = Integer.Parse(dr_("SEQUENCE").ToString())
                                workflowid = dr("WORKFLOWID").ToString()
                                Exit Function
                            End If
                        Next
                    End If
                End If
            Next
        Else '传入的批次当前工艺是子工艺
            isSubWorkflow = True
            Dim dt As DataTable = GetWorkFlowSetpsByWorkflowID(workflowid) '子工艺工序列表
            '循环寻找当前子工艺当前序以后有没有检验或者外委、转工记录的工序
            For Each dr As DataRow In dt.Rows
                If Integer.Parse(dr("SEQUENCE").ToString()) >= Sequence + 1 Then
                    If Not GetFinishCheckInfoOrStepCheckInfo(containerid, dr("WORKFLOWSTEPID"), dr("SEQUENCE"), workflowid, isShip) Then
                        isexistcount += 1
                        Continue For
                    Else
                        '如果工艺下一序不存在检验、外委、转工记录，则不用返回批次下一序的工序信息；存在则返回
                        GetNextStepNoCheckInfo = dr("WORKFLOWSTEPNAME").ToString() & "," & dr("WORKFLOWSTEPID").ToString() '返回下一序的工序信息
                        Sequence = Integer.Parse(dr("SEQUENCE").ToString())
                        Exit Function
                    End If
                End If
            Next
            '如果子工艺工序循环完之后还没有找到符合条件的工序，则到父工艺对应的当前子工艺工序的后面序
            Dim para As New Dictionary(Of String, String)
            para("WorkflowID") = father_workflow_dt.Rows(0)("WORKFLOWID") '父工艺ID
            Dim dt_ As DataTable = GetWorkFlowSetpsDetailByWorkflowID(para) '父工艺工序列表
            Sequence = 10000 '足够大已保证下面的循环判断在没赋值之前不执行
            For Each dr As DataRow In dt_.Rows '循环处理子工艺对应的父工艺工序列表
                If Not dr.IsNull("WORKFLOWID") Then
                    If dr("WORKFLOWID") = workflowid Then
                        Sequence = Integer.Parse(dr("SEQUENCE")) '获取子工艺在父工艺中对应的工序序号
                    End If
                    Continue For
                End If
                If Integer.Parse(dr("SEQUENCE").ToString()) >= Sequence + 1 Then
                    If dr("WFSTYPE").ToString() = "Spec" Then '正常序
                        If Not GetFinishCheckInfoOrStepCheckInfo(containerid, dr("WORKFLOWSTEPID"), dr("SEQUENCE"), para("WorkflowID"), isShip) Then
                            isexistcount += 1
                            Continue For
                        Else
                            '子工艺到父工艺正常序，不管是不是存在下一序有检验记录或外委、转工记录存在，都要返回父工艺ID、名称、版本以及没有存在记录的工序名称和ID
                            GetNextStepNoCheckInfo = dr("WORKFLOWSTEPNAME") & "," & dr("WORKFLOWSTEPID") & "," & father_workflow_dt.Rows(0)("WORKFLOWNAME") & "," &
                                father_workflow_dt.Rows(0)("WORKFLOWREVISION") & "," & father_workflow_dt.Rows(0)("FACTORYID")
                            Sequence = Integer.Parse(dr("SEQUENCE"))
                            workflowid = para("WorkflowID") '返回的是子工艺对应的父工艺ID
                            Exit Function
                        End If
                    Else '子工艺
                        Dim dt__ As DataTable = GetWorkFlowSetpsByWorkflowID(dr("WORKFLOWID").ToString()) '子工艺对应父工艺中的工序后面的子工艺工序的工序列表
                        '获取子工艺工序是否有外委或转工记录
                        '如果有则直接跳过该子工艺工序
                        If Not GetFinishCheckInfoOrStepCheckInfo(containerid, dr("WORKFLOWSTEPID"), dr("SEQUENCE"), para("WorkflowID"), isShip) Then
                            isexistcount += dt__.Rows.Count
                            Continue For
                        End If
                        '如果没有,则判断该子工艺工序是不是固定转工工序
                        If Not dr.IsNull("FACTORYID") Then
                            If dr("FACTORYID") <> factoryid Then '是固定转工工序，则直接跳出程序,下一序就是子工艺的第一序
                                GetNextStepNoCheckInfo = dt__.Rows(0)("WORKFLOWSTEPNAME") & "," & dt__.Rows(0)("WORKFLOWSTEPID") &
                                    "," & dr("WORKFLOWNAME") & "," & dr("WORKFLOWREVISION") & "," & dr("FACTORYID")
                                Sequence = Integer.Parse(dt__.Rows(0)("SEQUENCE"))
                                workflowid = dr("WORKFLOWID")
                                Exit Function
                            End If
                        End If
                        '进入子工艺工序查看工序是否存在外委或转工或检验记录
                        '并检查第一序是否存在外委或转工或检验记录，如果第一序不存在外委或转工或检验记录，则直接跳出程序
                        For Each dr_ As DataRow In dt__.Rows
                            If Not GetFinishCheckInfoOrStepCheckInfo(containerid, dr_("WORKFLOWSTEPID"), dr_("SEQUENCE"), dr("WORKFLOWID"), isShip) Then
                                isexistcount += 1
                                Continue For
                            Else
                                '子工艺到父工艺子工序，不管是不是存在下一序有检验记录或外委、转工记录存在，都要返回子工艺ID、名称、版本以及子工艺中没有存在记录的工序名称和ID
                                GetNextStepNoCheckInfo = dr_("WORKFLOWSTEPNAME") & "," & dr_("WORKFLOWSTEPID") & "," &
                                    dr("WORKFLOWNAME") & "," & dr("WORKFLOWREVISION") & "," & dr("FACTORYID")
                                Sequence = Integer.Parse(dr_("SEQUENCE"))
                                workflowid = dr("WORKFLOWID") '子工艺对应父工艺中的工序后面的子工艺工序的工艺ID
                                Exit Function
                            End If
                        Next
                    End If
                End If
            Next
        End If
    End Function

    ''' <summary>
    ''' 获取批次在某个工序是否存在检验记录 createtianFW 2018年3月5日
    ''' </summary>
    ''' <param name="containerid"></param>
    ''' <param name="workflowstpeid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetFinishCheckInfoOrStepCheckInfo(ByVal containerid As String, ByVal workflowstpeid As String, ByVal sequence As String, ByVal workflowid As String, ByVal isShipOut As Boolean) As Boolean
        '成品检验
        Dim strsql As New StringBuilder()
        strsql.AppendLine("SELECT * FROM CONTAINERFINISHEDCHECKINFO CFC")
        strsql.AppendLine("WHERE CFC.ISUSE=0")
        strsql.AppendFormat(" AND CFC.CONTAINERID='{0}' AND CFC.WORKFLOWSTEPID='{1}'", containerid, workflowstpeid)
        If DatabaseHelper.Query_ReturnDatTable(strsql.ToString()).Rows.Count = 0 Then
            '工序检验
            strsql.Clear()
            strsql.AppendLine("SELECT * FROM CONTAINERCHECKINFO CFO")
            strsql.AppendLine("WHERE CFO.ISUSE=0")
            strsql.AppendFormat(" AND CFO.CONTAINERID='{0}' AND CFO.WORKFLOWSTEPID='{1}'", containerid, workflowstpeid)
            If DatabaseHelper.Query_ReturnDatTable(strsql.ToString()).Rows.Count = 0 Then
                '如果已转工转出，则不需要再验证外委和转工信息
                If isShipOut Then
                    Return True
                End If
                '外委信息
                strsql.Clear()
                strsql.AppendLine("SELECT CC.CONTAINERCOMMISSIONINGID FROM CONTAINERCOMMISSIONING CC")
                strsql.AppendLine("LEFT JOIN WORKFLOWSTEP WS1 ON WS1.WORKFLOWSTEPID = CC.WORKFLOWSTEPID")
                strsql.AppendLine("LEFT JOIN WORKFLOWSTEP WS2 ON WS2.WORKFLOWSTEPID = CC.INWORKFLOWSTEPID")
                strsql.AppendLine("LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = WS1.WORKFLOWID")
                strsql.AppendLine("WHERE CC.INEMPLOYEEID IS NOT NULL AND CC.INDATE IS NOT NULL AND CC.ISUSE=0")
                strsql.AppendFormat(" AND WS1.SEQUENCE<={0} AND WS2.SEQUENCE>{0} AND CC.CONTAINERID='{1}'", sequence, containerid)
                strsql.AppendFormat(" AND WF.WORKFLOWID='{0}'", workflowid)
                If DatabaseHelper.Query_ReturnDatTable(strsql.ToString()).Rows.Count = 0 Then
                    '转工信息
                    strsql.Clear()
                    strsql.AppendLine("SELECT * FROM CONTAINERSHIPRECIVE CSR")
                    strsql.AppendLine("LEFT JOIN CONTAINERSHIPRECORDSTEP CSS ON CSS.CONTAINERSHIPRECORDID = CSR.CONTAINERSHIPRECORDID")
                    strsql.AppendLine("WHERE CSR.ISUSE=0 AND")
                    strsql.AppendFormat(" CSR.CONTAINERID='{0}' AND CSS.WORKFLOWSTEPID='{1}' ", containerid, workflowstpeid)
                    If DatabaseHelper.Query_ReturnDatTable(strsql.ToString()).Rows.Count = 0 Then
                        Return True
                    Else
                        Return False
                    End If
                Else
                    Return False
                End If
            Else
                Return False
            End If
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' '根据批次和子工艺路线获取父工艺信息 create tianFW  2018年3月8日
    ''' </summary>
    ''' <param name="containerid"></param>
    ''' <param name="subworkflowid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetFatherWorkflowInfo(ByVal containerid As String, ByVal subworkflowid As String) Implements uLMSCommonIBusiness.GetFatherWorkflowInfo
        Dim strsql_ As New StringBuilder
        strsql_.AppendLine("SELECT SFI.SUBWORKFLOWID,SFI.WORKFLOWID,WF.WORKFLOWREVISION,WB.WORKFLOWNAME,WF.FACTORYID FROM SUBWORKFLOWCHECKINFO SFI")
        strsql_.AppendLine("LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = SFI.WORKFLOWID")
        strsql_.AppendLine("LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        strsql_.AppendLine("WHERE 1=1 And ") 'SFI.CHECKTECHNIQUEID Is Not NULL  update:Wangjh 取消此项限制
        strsql_.AppendFormat("SFI.CONTAINERID='{0}' AND SFI.SUBWORKFLOWID='{1}'", containerid, subworkflowid)
        Return DatabaseHelper.Query_ReturnDatTable(strsql_.ToString())
    End Function

    ''' <summary>
    ''' 获取批次下一序进入固定转工的工艺ID、工序序号、工序ID create tianFW 2018年3月8日
    ''' </summary>
    ''' <param name="para_">批次当前工艺ID、当前工序ID、当前用户分厂ID</param>
    ''' <param name="containerid_">批次ID</param>
    ''' <param name="isSubWorkflow">批次当前工艺是否为子工艺</param>
    ''' <param name="workflowid_">批次下一序所在工艺ID,返回进入固定转工检验的工艺ID</param>
    ''' <param name="sequence_">批次下一序所在工艺的序号,返回进入固定转工检验的工序号</param>
    ''' <param name="strValueStepID">批次下一序的工序ID,返回进入固定转工检验的工序ID</param>
    ''' <remarks></remarks>
    Function GetFixShipWorkflowStepInfo(ByVal para_ As Dictionary(Of String, String), ByVal containerid_ As String, ByVal isSubWorkflow As Boolean, ByRef workflowid_ As String, ByRef sequence_ As Integer, ByRef strValueStepID As String) As String Implements uLMSCommonIBusiness.GetFixShipWorkflowStepInfo
        GetFixShipWorkflowStepInfo = para_("FactoryID")
        If Not isSubWorkflow Then '当前工艺不是子工艺
            Dim para = New Dictionary(Of String, String)
            Dim fatherWorkflowID = para_("WorkflowID") '父工艺ID
            para("WorkflowID") = fatherWorkflowID
            Dim newdt As DataTable = GetWorkFlowSetpsDetailByWorkflowID(para) '父工艺工序列表
            '如果传回的是子工艺ID，则需要验证子工艺工序是不是转工工序
            '如果不是子工艺，则传入的参数就是固定转工需要的参数
            If workflowid_ <> fatherWorkflowID Then '是子工艺
                For Each dr As DataRow In newdt.Rows '获取子工艺在父工艺对应的工序序号
                    If Not dr.IsNull("WORKFLOWID") Then
                        If dr("WORKFLOWID") = workflowid_ Then
                            If Not dr.IsNull("FACTORYID") Then
                                If dr("FACTORYID") <> para_("FactoryID") Then '是固定转工，则传入父工艺ID和子工艺工序序号和工序ID
                                    sequence_ = Integer.Parse(dr("SEQUENCE"))
                                    strValueStepID = dr("WORKFLOWSTEPID")
                                    workflowid_ = fatherWorkflowID '子工艺相当于父工艺工序，所以转工传参的工艺ID也应该是父工艺ID
                                Else
                                    '如果不是则直接判断传回来的子工艺的序（即批次下一序）的工艺ID（子工艺ID）和工序ID、工序序号
                                    '返回的分厂ID暂时取空，出去再取传回来的工艺的分厂ID                                                                     
                                    GetFixShipWorkflowStepInfo = ""
                                End If
                            End If
                            Exit For
                        End If
                    End If
                Next
            End If
        Else '当前工艺是子工艺
            Dim childerWorkflowID = para_("WorkflowID") '子工艺ID
            If workflowid_ <> childerWorkflowID Then '如果传回的是父工艺ID或者父工艺的其他子工艺ID
                Dim para = New Dictionary(Of String, String)
                Dim IsfatherWorkflow As Boolean = False '传入的是否是父工艺ID，不是则为父工艺的其他子工艺
                para("WorkflowID") = workflowid_ '传入的批次下一序的工艺ID
                Dim newdt As DataTable = GetWorkFlowSetpsDetailByWorkflowID(para) '批次下一序的工艺工序列表
                For Each dr As DataRow In newdt.Rows
                    If Not dr.IsNull("WORKFLOWID") Then
                        '如果存在当前子工艺工序ID，则说明传回的工艺ID是父工艺
                        If dr("WORKFLOWID") = para_("WorkflowID") Then
                            IsfatherWorkflow = True
                        End If
                    End If
                Next
                '如果传入不是父工艺ID，则需要判断传回的子工艺在父工艺对应的工序序号
                If Not IsfatherWorkflow Then '传回的是其他子工艺
                    Dim father_workflow_dt As DataTable = GetFatherWorkflowInfo(containerid_, workflowid_) '获取传回的子工艺的父工艺信息表
                    newdt = GetWorkFlowSetpsDetailByWorkflowID(father_workflow_dt.Rows(0)("WORKFLOWID")) '父工艺的工序详细列表
                    For Each dr As DataRow In newdt.Rows '获取子工艺在父工艺对应的工序序号
                        If Not dr.IsNull("WORKFLOWID") Then
                            If dr("WORKFLOWID") = workflowid_ Then
                                If Not dr.IsNull("FACTORYID") Then
                                    If dr("FACTORYID") <> para_("FactoryID") Then '是固定转工，则传入父工艺ID和子工艺工序序号和工序ID
                                        sequence_ = Integer.Parse(dr("SEQUENCE"))
                                        strValueStepID = dr("WORKFLOWSTEPID")
                                        workflowid_ = father_workflow_dt.Rows(0)("WORKFLOWID") '子工艺相当于父工艺工序，所以转工传参的工艺ID也应该是父工艺ID
                                    Else '如果不是则传入的子工艺的序（即批次下一序）的工艺ID（子工艺ID）和工序ID、工序序号就是固定转工需要的参数
                                        GetFixShipWorkflowStepInfo = ""
                                    End If
                                End If
                                Exit For
                            End If
                        End If
                    Next
                End If
            Else
                GetFixShipWorkflowStepInfo = ""
            End If
        End If
    End Function

    ''' <summary>
    ''' 获取批次指定工艺未加工完的工序
    ''' add:Wangjh 2018-3-2
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetContainerNoCompleteStep(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetContainerNoCompleteStep
        Dim Originalfactoryid As String = ""
        Dim productName As String = ""
        Dim containerName As String = ""
        Dim workflowID As String = ""
        Dim containerID As String = ""
        Dim workflowroute As String = ""
        Dim strSql As String = ""

        strSql = String.Format("SELECT cci.* FROM containercurrentinfo cci WHERE cci.containerid='{0}'", para("ContainerID"))
        Dim temDt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        If temDt.Rows.Count = 0 Then
            Return Nothing
        End If
        Originalfactoryid = temDt.Rows(0)("originalfactoryid").ToString '批次开卡分厂
        productName = temDt.Rows(0)("productname").ToString
        containerName = temDt.Rows(0)("containername").ToString
        If para.ContainsKey("WorkFlowID") Then
            workflowID = para("WorkFlowID")
        Else
            workflowID = temDt.Rows(0)("WorkFlowID").ToString
        End If
        containerID = temDt.Rows(0)("ContainerID").ToString
        workflowroute = temDt.Rows(0)("workflowroute").ToString

        strSql = <string>SELECT WS.WORKFLOWSTEPNAME,WS.WORKFLOWSTEPID,WS.SEQUENCE,
                WB.WORKFLOWNAME,W.WORKFLOWREVISION,NVL(WS.CONTROLCODE,S.CONTROLCODE) CONTROLCODE,
                ws.wipmsglabel,s.factoryid FROM WORKFLOWSTEP WS 
				LEFT JOIN WORKFLOW W ON W.WORKFLOWID=WS.WORKFLOWID   
                LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID=W.WORKFLOWBASEID      
                LEFT JOIN specbase sb ON sb.specbaseid=ws.specbaseid
                LEFT JOIN spec s ON s.specid=NVL(sb.revofrcdid,ws.specid)
                LEFT JOIN  (SELECT containerstepNoShipid,workflowstepid FROM  containerstepNoShip cns </string>
        strSql += String.Format(" WHERE cns.containerid='{0}' ", para("ContainerID")) '筛选掉不加工的工序
        strSql += <string>AND cns.isuse=0  AND cns.noship=2) cns ON  cns.workflowstepid=ws.workflowstepid       
               where  1=1 and NVL(cns.containerstepNoShipid,'0')='0' and NVL2(ws.sequence,1,0)=1           
                </string>.Value 'ws.steptype=1 update:wangjh 20220418此条件取消

        strSql += String.Format(" AND w.workflowid='{0}'", workflowID)
        If para.ContainsKey("Sequence") Then
            strSql += String.Format(" AND ws.sequence>={0}", para("Sequence"))
        End If
        If para.ContainsKey("WorkflowstepIDs") Then '指定检查的工序
            strSql += String.Format(" AND ws.WORKFLOWSTEPID in ({0})", para("WorkflowstepIDs"))
        End If
        'strSql += " UNION "
        'strSql += <string>SELECT WS.WORKFLOWSTEPNAME,WS.WORKFLOWSTEPID,WS.SEQUENCE,WB.WORKFLOWNAME,W.WORKFLOWREVISION,ws.controlcode FROM WORKFLOWSTEP WS 
        '                    LEFT JOIN WORKFLOW W ON W.WORKFLOWID=WS.WORKFLOWID   
        '                    LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID=W.WORKFLOWBASEID    
        '                    LEFT JOIN Workflowbase subwb ON subwb.workflowbaseid=ws.subworkflowbaseid
        '                    LEFT JOIN Workflow subw ON subw.workflowid=NVL(subwb.revofrcdid,ws.subworkflowid)
        '                    LEFT JOIN Workflowbase wb2 ON wb2.workflowbaseid=subw.workflowbaseid
        '        </string>.Value
        'strSql += " where ws.steptype=2 "
        'strSql += String.Format(" AND w.workflowid='{0}' AND subw.factoryid<>'{1}'", para("WorkFlowID"), Originalfactoryid)
        'If para.ContainsKey("Sequence") Then
        '    strSql += String.Format(" AND ws.sequence>={0}", para("Sequence"))
        'End If

        strSql += " ORDER BY WS.SEQUENCE ASC"
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        Dim dt1 = dt.Clone
        Dim stepComdt As New DataTable
        If para.ContainsKey("Sequence") Then
            stepComdt = IsContainerStepComplete(para("ContainerID"), String.Empty, Val(para("Sequence")))
        Else
            stepComdt = IsContainerStepComplete(para("ContainerID"), String.Empty)
        End If

        For Each row As DataRow In dt.Rows '筛选未干完的工序
            If stepComdt.Select(String.Format("workflowstepid='{0}'", row("WorkflowstepID"))).Length = 0 Then
                dt1.ImportRow(row)
            End If
        Next
        dt1.AcceptChanges()
        If dt1.Rows.Count = 0 Then
            Return dt1
        End If

        '查出转工或者外委已经干完的工序
        strSql = <string>SELECT WS.WORKFLOWSTEPNAME,WS.WORKFLOWSTEPID,WS.SEQUENCE,WB.WORKFLOWNAME,
                   W.WORKFLOWREVISION,NVL(WS.CONTROLCODE,S.CONTROLCODE) CONTROLCODE,
                    ws.wipmsglabel,s.factoryid FROM containershiprecordstep csrs 
                    LEFT JOIN workflowstep ws ON ws.workflowstepid=csrs.workflowstepid
                    LEFT JOIN containershiprecive csre ON csre.containershiprecordid=csrs.containershiprecordid
                    LEFT JOIN Workflow w ON w.workflowid=ws.workflowid
                    LEFT JOIN Workflowbase wb ON wb.workflowbaseid=w.workflowbaseid
                    LEFT JOIN specbase sb ON sb.specbaseid=ws.specbaseid
                LEFT JOIN spec s ON s.specid=NVL(sb.revofrcdid,ws.specid)
                    WHERE csre.recivedate IS NOT NULL and csre.isuse=0
               </string>
        strSql += String.Format(" AND csre.containerid='{0}' AND  ws.workflowid='{1}'", para("ContainerID"), workflowID)
        If para.ContainsKey("Sequence") Then
            strSql += String.Format(" AND ws.sequence>={0}", para("Sequence"))
        End If
        If para.ContainsKey("WorkflowstepIDs") Then '指定检查的工序
            strSql += String.Format(" AND ws.WORKFLOWSTEPID in ({0})", para("WorkflowstepIDs"))
        End If
        strSql += <string> UNION ALL SELECT WS3.WORKFLOWSTEPNAME,WS3.WORKFLOWSTEPID,
                WS3.SEQUENCE,WB.WORKFLOWNAME,W.WORKFLOWREVISION,ws3.controlcode,ws3.wipmsglabel,
                s.factoryid FROM containercommissioning cmm
                 LEFT JOIN workflowstep ws ON ws.workflowstepid=cmm.workflowstepid
                 LEFT JOIN workflowstep ws2 ON ws2.workflowstepid=cmm.inworkflowstepid
                 LEFT JOIN Workflowstep ws3 ON ws3.workflowid=ws.workflowid 
                 LEFT JOIN workflow w ON w.workflowid=ws3.workflowid
                LEFT JOIN Workflowbase wb ON wb.workflowbaseid=w.workflowbaseid
                 LEFT JOIN specbase sb ON sb.specbaseid=ws3.specbaseid
                 LEFT JOIN spec s ON s.specid=NVL(sb.revofrcdid,ws3.specid)
                 WHERE cmm.indate IS NOT NULL AND cmm.isuse=0 </string>.Value
        strSql += String.Format(" AND ws3.sequence>=ws.sequence AND ws3.sequence<ws2.sequence AND cmm.containerid='{0}' AND  ws3.workflowid='{1}'", para("ContainerID"), workflowID)
        If para.ContainsKey("Sequence") Then
            strSql += String.Format(" AND ws3.sequence>={0}", para("Sequence"))
        End If
        If para.ContainsKey("WorkflowstepIDs") Then '指定检查的工序
            strSql += String.Format(" AND ws3.WORKFLOWSTEPID in ({0})", para("WorkflowstepIDs"))
        End If
        Dim dt2 As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        Dim temp = dt1.AsEnumerable.Except(dt2.AsEnumerable, DataRowComparer.Default)
        If temp.Count = 0 Then '干完了
            Return dt.Clone
        End If
        dt1 = temp.CopyToDataTable
        dt1.AcceptChanges() '未干完的工序信息

        '判断将要移到的序是否是本分厂的子工艺序（假设当前卡有子卡） update:wangjh 20220420 重写此业务逻辑
        strSql = <string> select distinct cci.containerid,cci.containername,cci.workflowid,cci.workflowstepid,cci.isinstore from containersubcontainer cc
                                left join containercurrentinfo cci on cci.containerid=cc.subcontainerid
                                where cc.containerid='{0}'  </string>.Value
        strSql = String.Format(strSql, para("ContainerID"))
        Dim allSonDt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)

        If allSonDt.Rows.Count > 0 Then
            Dim result As DataTable = dt1.Clone
            For Each row As DataRow In dt1.Rows
                If row("factoryid").ToString = Originalfactoryid And row("wipmsglabel").ToString = "子工艺" Then '本分厂的子工艺序
                    Dim sonDrs = allSonDt.Select("workflowstepid='" + row("workflowstepid").ToString + "'")
                    If sonDrs.Length > 0 Then
                        Dim sondt As DataTable = sonDrs.CopyToDataTable
                        If sondt.Select("isinstore=0 or isinstore=-1").Length = 0 Then '循环序的子卡干完了
                            Continue For
                        End If
                    End If
                End If
                result.ImportRow(row)
            Next
            '获取了之后的所有序
            result.DefaultView.Sort = " SEQUENCE asc"
            result = result.DefaultView.ToTable
            result.AcceptChanges()
            'Return result
            dt1 = result
        End If

        dt1.Columns.Add("WorkflowID")
        dt1.Columns.Add("ContainerID")
        dt1.Columns.Add("ContainerName")
        If dt1.Rows.Count > 0 Then
            dt1.Rows(0)("WorkflowID") = workflowID
            dt1.Rows(0)("ContainerID") = containerID
            dt1.Rows(0)("ContainerName") = containerName
        End If

        GetContainerNoCompleteStep = dt1
    End Function
    ''' <summary>
    ''' 检查主卡是否应该移动并返回参数
    ''' add:Wangjh 20181205
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CheckFaContainerAndReturnMoveInfo(ByVal para As Dictionary(Of String, String), ByRef resMsg As String) As Dictionary(Of String, String) Implements uLMSCommonIBusiness.CheckFaContainerAndReturnMoveInfo
        '主子工序信息
        Dim strSql As String = ""
        'strSql = String.Format(" SELECT WorkflowStepID FROM stepsubstep sus WHERE sus.sonworkflowstepid='{0}' GROUP BY sus.workflowstepid", para("WorkflowStepID"))
        'Dim stepDt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        'If stepDt.Rows.Count = 0 Then
        '    resMsg = "此子卡的工序无对应的主工序"
        '    Return Nothing
        'End If
        '子卡的一些信息
        strSql = String.Format(" SELECT cci.*  FROM containercurrentinfo cci WHERE cci.containerstatus=1 AND cci.ContainerID='{0}'", para("ContainerID"))
        Dim sonContainerDt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        If sonContainerDt.Rows.Count = 0 Then
            Return Nothing
        End If
        Dim sonContainerRow As DataRow = sonContainerDt.Rows(0)

        '查询主卡信息,主卡还在开子卡时的工序上
        Dim faContainerDt As New DataTable

        strSql = <string> select cci.containerid,cci.containername,cci.productname,cci.workflowstepsequence,cci.workflowid,cci.OriginalFactoryID,cci.qty,cci.workflowstepid  from containersubcontainer cc
left join containercurrentinfo cci on cci.containerid=cc.containerid and cci.workflowstepid=cc.workflowstepid
where cc.subcontainerid='{0}' and cci.containerid is not null and not exists (
select 1 from containershiprecord csr where csr.containershiprecordid=cci.shipid 
and csr.toworkflowstepid=cci.workflowstepid and csr.isuse=0
)
GROUP BY cci.containerid,cci.containername,cci.productname,cci.workflowstepsequence,cci.workflowid,cci.OriginalFactoryID,cci.qty,cci.workflowstepid </string>.Value
        strSql = String.Format(strSql, para("ContainerID"))
        faContainerDt = DatabaseHelper.Query_ReturnDatTable(strSql)

        If faContainerDt.Rows.Count = 0 Then '无对应主工序的主卡
            resMsg = "此子卡无对应符合移动条件的主卡"
            Return Nothing
        End If
        If faContainerDt.Rows.Count > 1 Then '存在多个主卡
            resMsg = "此子卡对应多个主卡"
            Return Nothing
        End If
        If faContainerDt.Rows(0)("OriginalFactoryID").ToString <> sonContainerRow("OriginalFactoryID").ToString Then '主卡与子卡分厂不一致
            'resMsg = "此子卡与主卡开卡分厂不一致"
            'Return Nothing
        End If
        '检查主卡此工序上的其他子卡是否干完
        strSql = <string>select scci.*  from containersubcontainer cc
left join containercurrentinfo scci on scci.containerid=cc.subcontainerid
where cc.containerid='{0}' and cc.workflowstepid='{1}' and scci.containerid!='{2}' and scci.isinstore in (-1,0) </string>.Value

        Dim otherSonDt As DataTable = DatabaseHelper.Query_ReturnDatTable(String.Format(strSql, faContainerDt.Rows(0)("containerid").ToString,
                                                                          faContainerDt.Rows(0)("workflowstepid").ToString, para("ContainerID")))

        If otherSonDt.Rows.Count > 0 Then
            resMsg = "有子卡未干完，主卡不移动"
            Return Nothing
        End If

        Dim compeletePara As New Dictionary(Of String, String)
        '子卡已干完，移动主卡的信息
        compeletePara.Clear()
        compeletePara.Add("ContainerID", faContainerDt.Rows(0)("ContainerID").ToString)
        compeletePara.Add("WorkFlowID", faContainerDt.Rows(0)("WorkFlowID").ToString)
        compeletePara.Add("WorkflowID", faContainerDt.Rows(0)("WorkFlowID").ToString) '兼容一下
        compeletePara.Add("Sequence", Val(faContainerDt.Rows(0)("workflowstepsequence").ToString) + 1)
        compeletePara.Add("WipQty", faContainerDt.Rows(0)("qty").ToString)
        compeletePara.Add("ContainerName", faContainerDt.Rows(0)("ContainerName").ToString)
        Return compeletePara
    End Function

    ''' <summary>
    ''' 获取员工列表
    ''' add by YangJiang 20180208
    ''' </summary>
    Public Function GetEmployee(ByVal workcenterID As String, ByVal factoryID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetEmployee
        Dim strSQL As New StringBuilder
        strSQL.AppendLine("SELECT sv.factoryid,sv.workcenterid,em.* FROM employee em")
        strSQL.AppendLine(" LEFT JOIN Sessionvalues sv ON em.employeeid=sv.employeeid")


        'strSQL.AppendLine("LEFT JOIN teamemployee tem ON tem.employeeid = em.employeeid")
        'strSQL.AppendLine("LEFT JOIN team t ON t.teamid = tem.teamid ")
        'strSQL.AppendLine("LEFT JOIN Workcenter w ON w.workcenterid=t.workcenterid")

        strSQL.AppendFormat("WHERE sv.factoryid='{0}'", factoryID)
        If Not IsNothing(workcenterID) Then
            strSQL.AppendFormat("AND sv.workcenterid='{0}'", workcenterID)
        End If

        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSQL.ToString)
        If dt Is Nothing Then
            GetEmployee = New DataTable
        Else
            GetEmployee = dt
        End If
    End Function

    ''' <summary>
    ''' 根据员工ID查询已有的设备数量  add by YangJiang  20180208
    ''' </summary>
    ''' <param name="EmployeeID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetResourceCountByEmployeeid(ByVal EmployeeID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetResourceCountByEmployeeid
        Dim strSQL As String = String.Format("SELECT COUNT(*) ResourceCount FROM employeeresourcelist emreli WHERE emreli.employeeid='{0}'", EmployeeID)
        Return DatabaseHelper.Query_ReturnDatTable(strSQL)
    End Function

    ''' <summary>
    ''' 根据员工ID查询已有的报表数量  add by YangJiang  20180208
    ''' </summary>
    ''' <param name="EmployeeID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetReportPageCountByEmployeeid(ByVal EmployeeID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetReportPageCountByEmployeeid
        Dim strSQL As String = String.Format("SELECT COUNT(*) ReportPageCount FROM EMPLOYEEREPORTPAGE er WHERE er.employeeid='{0}'", EmployeeID)
        Return DatabaseHelper.Query_ReturnDatTable(strSQL)
    End Function

    ''' <summary>
    ''' 根据员工id获取资源信息（员工可多选） Create YangJiang  20180208
    ''' </summary>
    ''' <param name="employeeids"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetResourceDefByemployeeid1(ByVal employeeids() As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetResourceDefByemployeeid1
        Dim strSql As New StringBuilder
        strSql.AppendLine("SELECT re.description||'('||re.resourcename||')' RESNAME,re.resourcename,re.resourceid FROM resourcedef re")
        strSql.AppendLine("LEFT JOIN employeeresourcelist emreli ON emreli.resourcelistid = re.resourceid")
        strSql.AppendLine("LEFT JOIN employee em ON em.employeeid = emreli.employeeid ")
        If employeeids.Length = 1 Then
            strSql.AppendFormat("WHERE EM.EMPLOYEEID='{0}'", employeeids(0))
        Else
            strSql.AppendFormat("WHERE EM.EMPLOYEEID='{0}'", employeeids(0))
            For i = 1 To employeeids.Length - 1
                strSql.AppendFormat("OR EM.EMPLOYEEID='{0}'", employeeids(i))
            Next
            strSql.AppendLine(" GROUP BY re.description||'('||re.resourcename||')',re.resourcename,re.resourceid")
            strSql.AppendFormat(" HAVING COUNT(re.description||'('||re.resourcename||')')={0}", employeeids.Length)
        End If

        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql.ToString)
        If dt Is Nothing Then
            GetResourceDefByemployeeid1 = New DataTable
        Else
            GetResourceDefByemployeeid1 = dt
        End If
    End Function

    ''' <summary>
    ''' 根据员工ID获取ReportPage(员工可多选) Create YangJiang 20180208
    ''' </summary>
    ''' <param name="employeeID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetReportPageByEmployeeID1(ByVal employeeID() As String) As DataTable Implements uLMSCommonIBusiness.GetReportPageByEmployeeID1
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT RP.REPORTPAGENAME,RP.PAGEURL,RP.ISLOOKBOARD FROM REPORTPAGE RP")
        strsql.AppendLine("LEFT JOIN EMPLOYEEREPORTPAGE EP ON RP.REPORTPAGEID = EP.REPORTPAGEID")
        strsql.AppendLine("LEFT JOIN EMPLOYEE EM ON  EP.EMPLOYEEID = EM.EMPLOYEEID")

        If employeeID.Length = 1 Then
            strsql.AppendFormat("WHERE EM.EMPLOYEEID='{0}'", employeeID(0))
        Else
            strsql.AppendFormat("WHERE EM.EMPLOYEEID='{0}'", employeeID(0))
            For i = 1 To employeeID.Length - 1
                strsql.AppendFormat("OR EM.EMPLOYEEID='{0}'", employeeID(i))
            Next
            strsql.AppendLine(" GROUP BY RP.REPORTPAGENAME,RP.PAGEURL,RP.ISLOOKBOARD")
            strsql.AppendFormat("  HAVING COUNT(RP.REPORTPAGENAME)={0}", employeeID.Length)
        End If

        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取件号默认以及其他版本的工艺路线信息 create by tianFW 2018年8月2日
    ''' </summary>
    ''' <param name="para"></param>
    ''' <param name="GetChildWF"></param>
    ''' <param name="IsThisFactory"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetProductAllRevWFInfo(ByVal para As Dictionary(Of String, String), ByVal GetChildWF As Boolean, ByVal IsThisFactory As Boolean) As DataTable Implements uLMSCommonIBusiness.GetProductAllRevWFInfo
        '获取件号默认版本工艺及其其他版本工艺、子工艺
        Dim dtmr As DataTable = GetWorkflowInfoWithOtherAndSubByProductInfo(para, GetChildWF, IsThisFactory)
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT p.productrevision prevision FROM product p")
        strsql.AppendLine("LEFT JOIN productbase pb ON pb.productbaseid = p.productbaseid")
        strsql.AppendFormat("WHERE pb.productname='{0}' AND p.productrevision<>'{1}'", para("ProductName"), para("ProductRev"))
        '及那好其他版本的默认工艺及其其他版本工艺、子工艺
        Dim otherPro_dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
        Dim otherProWF_dt As DataTable
        If otherPro_dt.Rows.Count > 0 Then
            For Each dr As DataRow In otherPro_dt.Rows
                para("ProductRev") = dr("prevision")
                otherProWF_dt = New DataTable
                otherProWF_dt = GetWorkflowInfoWithOtherAndSubByProductInfo(para, GetChildWF, IsThisFactory)
                For Each dr_ As DataRow In otherProWF_dt.Rows
                    If dr_("WORKFLOWNAME").ToString().Contains("默认") Then
                        dr_("WORKFLOWNAME") = dr_("WORKFLOWNAME").ToString().Replace("默认", "")
                        Exit For
                    End If
                Next
                dtmr.Merge(otherProWF_dt)
            Next
        End If
        If dtmr.Rows.Count > 0 Then
            Return dtmr.DefaultView.ToTable(True, "WORKFLOWID", "WORKFLOWNAME", "FACTORYID")
        Else
            Return New DataTable
        End If
    End Function

    ''' <summary>
    ''' 获取件号下默认工艺以及其他版本工艺和默认工艺子工艺信息、件号历史使用的其他工艺 create tianFW 2018年3月15日
    ''' 添加如果是装试分厂，由件号到工艺的查询方法调整 Modify by Yuxj20180720
    ''' </summary>
    ''' <param name="para"></param>
    ''' <param name="GetChildWF">是否显示子工艺工艺路线</param>
    ''' <param name="IsThisFactory">是否只显示当前分厂工艺</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkflowInfoWithOtherAndSubByProductInfo(ByVal para As Dictionary(Of String, String), ByVal GetChildWF As Boolean, ByVal IsThisFactory As Boolean) As DataTable Implements uLMSCommonIBusiness.GetWorkflowInfoWithOtherAndSubByProductInfo
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WF.WORKFLOWID,WFB1.WORKFLOWBASEID,WFB1.WORKFLOWNAME || ':' || WF.WORKFLOWREVISION || '(' || WF.WORKFLOWTYPE || ')' WORKFLOWNAME,")
        sb.AppendLine("WF.FACTORYID,P.PRODUCTID,NVL(wf.isuse,'0') isuse")
        sb.AppendLine(" FROM PRODUCT P")
        sb.AppendLine("  LEFT JOIN PRODUCTBASE PB ON P.PRODUCTBASEID = PB.PRODUCTBASEID")
        sb.AppendLine("  LEFT JOIN WORKFLOWBASE WFB ON WFB.WORKFLOWBASEID = P.WORKFLOWBASEID")
        sb.AppendLine("  LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = NVL(WFB.REVOFRCDID, P.WORKFLOWID)")
        sb.AppendLine("  LEFT JOIN WORKFLOWBASE WFB1 ON WFB1.WORKFLOWBASEID = WF.WORKFLOWBASEID")
        sb.AppendFormat(" WHERE PB.PRODUCTNAME = '{0}' AND P.PRODUCTREVISION = '{1}'", para("ProductName"), para("ProductRev"))
        'Modify YangJiang 20180726 增加按工艺名称查询
        If para.Keys.Contains("WorkFlowName") Then
            If Not String.IsNullOrWhiteSpace(para("WorkFlowName")) Then
                sb.AppendFormat(" AND WFB1.WORKFLOWNAME LIKE '%{0}%'", para("WorkFlowName"))
            End If
        End If



        '件号默认工艺路线信息

        'Modify by Yuxj20180720
        If para.ContainsKey("ZS") Then
            sb = New StringBuilder
            sb.AppendLine("SELECT WF.WORKFLOWID,WFB.WORKFLOWBASEID,WFB.WORKFLOWNAME || ':' || WF.WORKFLOWREVISION || '(' || WF.WORKFLOWTYPE || ')' WORKFLOWNAME,")
            sb.AppendLine("WF.FACTORYID,P.PRODUCTID,NVL(wf.isuse,'0') isuse ")
            sb.AppendLine(" FROM PRODUCT P")
            sb.AppendLine("  LEFT JOIN PRODUCTBASE PB ON P.PRODUCTBASEID = PB.PRODUCTBASEID")
            sb.AppendLine("  INNER JOIN productworkflowmapping pw ON p.productid=pw.productid")
            sb.AppendLine("  INNER JOIN WORKFLOW WF ON WF.WORKFLOWID = pw.WORKFLOWID")
            sb.AppendLine("  INNER JOIN WORKFLOWBASE WFB ON WFB.WORKFLOWBASEID = wf.WORKFLOWBASEID")
            sb.AppendFormat(" WHERE PB.PRODUCTNAME = '{0}' AND P.PRODUCTREVISION = '{1}'", para("ProductName"), para("ProductRev"))

            'add by longb 2023-06-19 查询施工单、技通单（分解之后对应的订单件号信息）工艺用于排产
            sb.AppendLine(<string>UNION ALL
             SELECT WF.WORKFLOWID,WFB.WORKFLOWBASEID,WFB.WORKFLOWNAME || ':' || WF.WORKFLOWREVISION || '(' || (case WHEN e."TYPE"=2 THEN  WF.WORKFLOWTYPE ELSE replace(WF.WORKFLOWTYPE,'施工','技通')end) || ')' WORKFLOWNAME,
             WF.FACTORYID,e.PRODUCTID ,NVL(wf.isuse,'0') isuse 
             FROM ENGINEPARTPLAN e 
             LEFT JOIN PRODUCT P ON P.PRODUCTID=e.PRODUCTID
             LEFT JOIN PRODUCTBASE PB ON P.PRODUCTBASEID = PB.PRODUCTBASEID
             INNER JOIN WORKFLOW WF ON WF.WORKFLOWID = e.WORKFLOWID
             INNER JOIN WORKFLOWBASE WFB ON WFB.WORKFLOWBASEID = wf.WORKFLOWBASEID</string>)
            sb.AppendFormat("WHERE WF.WORKFLOWTYPE='施工工艺' AND PB.PRODUCTNAME = '{0}' AND P.PRODUCTREVISION = '{1}'", para("ProductName"), para("ProductRev"))
        End If
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString())
        If dt.Rows.Count = 0 Then 'add YangJiang 20180727
            Return New DataTable
        End If
        If dt.Rows.Count = 1 And IsDBNull(dt.Rows(0)("WORKFLOWID")) Then
            Return New DataTable
        End If

        Dim dr = dt.Rows(0)
        '给件号默认工艺路线标上‘默认’标识
        Dim workflowidMR As String = dr("WORKFLOWID")
        Dim sub_dt As New DataTable '子工艺'
        Dim other_dt As New DataTable '默认工艺的其他版本工艺
        Dim PWM_dt As New DataTable '工艺、件号关联工艺信息表
        If GetChildWF = True Then
            Dim newpara As New Dictionary(Of String, String)
            newpara("WorkflowID") = dr("WORKFLOWID")
            newpara("ChildWorkflow") = "ChildWorkflow"
            Dim sub_dt_detail As DataTable = GetWorkFlowSetpsDetailByWorkflowID(newpara)
            For Each dr_ As DataRow In sub_dt_detail.Rows
                dr_("WORKFLOWNAME") = dr_("WORKFLOWNAME") + ":" + dr_("WORKFLOWREVISION") + "(" + dr_("WORKFLOWTYPE") + ")"
            Next
            sub_dt = sub_dt_detail.DefaultView.ToTable(True, "WORKFLOWID", "WORKFLOWNAME", "FACTORYID", "isuse")
        End If
        Dim dt_other = GetWorkFlowOtherRevision(dr("WORKFLOWID"), dr("WORKFLOWBASEID"))
        other_dt = dt_other.DefaultView.ToTable(True, "WORKFLOWID", "WORKFLOWNAME", "FACTORYID", "isuse")
        Dim dt_PWM As DataTable = GetWorkFlowInfoByProductID(dr("PRODUCTID"))
        PWM_dt = dt_PWM.DefaultView.ToTable(True, "WORKFLOWID", "WORKFLOWNAME", "FACTORYID", "isuse")
        Dim value As DataTable = dt.DefaultView.ToTable(True, "WORKFLOWID", "WORKFLOWNAME", "FACTORYID", "isuse")
        If sub_dt.Rows.Count > 0 Then
            value.Merge(sub_dt)
        End If
        If other_dt.Rows.Count > 0 Then
            value.Merge(other_dt)
        End If
        If PWM_dt.Rows.Count > 0 Then
            value.Merge(PWM_dt)
        End If
        Dim value_dt = value.DefaultView.ToTable(True, "WORKFLOWID", "WORKFLOWNAME", "FACTORYID", "isuse")
        For Each dr_ As DataRow In value_dt.Rows
            If dr_("WORKFLOWID") = workflowidMR Then
                dr_("WORKFLOWNAME") = dr_("WORKFLOWNAME") + "默认"
                Exit For
            End If
        Next

        '筛选工艺路线是否有效 by duht add 20240809
        Dim dt_temp = value_dt.DefaultView
        If para.Keys.Contains("WorkFlowIsUse") Then
            If Not String.IsNullOrWhiteSpace(para("WorkFlowIsUse")) Then
                dt_temp.RowFilter = String.Format("isuse='{0}'", para("WorkFlowIsUse"))
            End If
        End If
        dt_temp.ToTable().AcceptChanges()
        dt_temp = dt_temp.ToTable(True).DefaultView
        'end
        If IsThisFactory Then
            'Dim dv = value_dt.DefaultView
            dt_temp.RowFilter = String.Format("FACTORYID='{0}'", para("FactoryID"))
            Return dt_temp.ToTable()
        Else
            Return dt_temp.ToTable()
        End If
    End Function

    ''' <summary>
    ''' 通过件号id在工艺、件号中间表获取工艺信息 create tianFW 
    ''' </summary>
    ''' <param name="productid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkFlowInfoByProductID(ByVal productid As String) As DataTable Implements uLMSCommonIBusiness.GetWorkFlowInfoByProductID
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WF.WORKFLOWID,wb.WORKFLOWBASEID,wb.WORKFLOWNAME || ':' || WF.WORKFLOWREVISION || '(' || WF.WORKFLOWTYPE || ')' WORKFLOWNAME,WF.FACTORYID,NVL(wf.isuse,'0') isuse ")
        sb.AppendLine("FROM productworkflowmapping pwm")
        sb.AppendLine("LEFT JOIN workflow wf ON wf.workflowid = pwm.workflowid")
        sb.AppendLine("LEFT JOIN workflowbase wb ON wb.workflowbaseid = wf.workflowbaseid")
        sb.AppendFormat(" WHERE pwm.productid='{0}'", productid)
        Return DatabaseHelper.Query_ReturnDatTable(sb.ToString())
    End Function

    ''' <summary>
    ''' 根据班获取员工列表(ZS)  Create:YangJiang  20180320
    ''' </summary>
    ''' <param name="ShiftID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEmployeeInfoByShiftID(ByVal ShiftID As String, ByVal FactoryID As String, ByVal WorkcenterID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetEmployeeInfoByShiftID
        Dim strSQL As New StringBuilder
        strSQL.AppendLine("SELECT E.*,S.* FROM EMPLOYEE E LEFT JOIN SHIFT S ON E.SHIFTID=S.SHIFTID ")
        strSQL.AppendLine("LEFT JOIN Sessionvalues sv ON e.employeeid=sv.employeeid")
        strSQL.AppendFormat("WHERE S.SHIFTID='{0}'", ShiftID)
        strSQL.AppendFormat(" AND SV.FACTORYID='{0}'", FactoryID)
        strSQL.AppendFormat(" AND SV.WORKCENTERID='{0}'", WorkcenterID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSQL.ToString)
        If dt Is Nothing Then
            GetEmployeeInfoByShiftID = New DataTable
        Else
            GetEmployeeInfoByShiftID = dt
        End If
    End Function

    ''' <summary>
    ''' 获取工艺的所有子工艺信息合并之后
    ''' add:Wangjh 20180322
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSubWorkFlowInfoOfWorkFlow(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetSubWorkFlowInfoOfWorkFlow
        Dim strSql As String = <string>
                SELECT subw.process_no subprocess_no,wm_concat( substr(ws.workflowstepname,0,INSTR(ws.workflowstepname,'-')-1)) specno FROM workflow w 
                LEFT JOIN workflowstep ws ON ws.workflowid=w.workflowid AND ws.steptype=2
                LEFT JOIN workflowbase sube ON sube.workflowbaseid=ws.subworkflowbaseid
                LEFT JOIN workflow subw ON subw.workflowid=NVL(sube.revofrcdid,ws.subworkflowid)
                LEFT JOIN workflowbase sube2 ON sube2.workflowbaseid=subw.workflowbaseid                             
                </string>
        strSql += String.Format(" WHERE w.workflowid='{0}'", para("WorkFlowID"))
        strSql += "group by subw.process_no"
        GetSubWorkFlowInfoOfWorkFlow = DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 修改批次的主制工区信息 create tianFW 2018年3月29日
    ''' </summary>
    ''' <param name="ContainerID">批次id</param>
    ''' <param name="WorkCenterID">工区id</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ChangeWorkCenter(ByRef ContainerID As String, ByVal WorkCenterID As String, ByRef message As String) As Boolean Implements uLMSCommonIBusiness.ChangeWorkCenter
        Dim strsql As New StringBuilder
        Try
            strsql.AppendFormat("UPDATE CONTAINER C SET C.WORKCENTERID='{0}' WHERE C.CONTAINERID='{1}'", WorkCenterID, ContainerID)
            If DatabaseHelper.ExecuteSql(strsql.ToString()) > 0 Then
                Dim wcdt As DataTable = GetWorkCenterInfoByWorkCenterID(WorkCenterID)
                strsql.Clear()
                strsql.AppendLine("UPDATE CONTAINERCURRENTINFO CU SET")
                strsql.AppendFormat(" CU.FROMWORKCENTERID='{0}',CU.FROMWORKCENTERNAME='{1}',CU.WORKCENTERID='{0}',CU.WORKCENTERNAME='{1}'", WorkCenterID, wcdt.Rows(0)("WORKCENTERNAME"))
                strsql.AppendFormat(" WHERE CU.CONTAINERID='{0}'", ContainerID)
                If DatabaseHelper.ExecuteSql(strsql.ToString()) > 0 Then
                    Return True
                End If
            End If
        Catch ex As Exception
            message = ex.Message
        End Try
        Return False
    End Function

    ''' <summary>
    ''' 工序是否工艺最后序
    ''' </summary>
    ''' <param name="strStepID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function IsLastStepFinished(ByVal strStepID As String) As Boolean
        IsLastStepFinished = False
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT WF.DEFAULTPATHID, WF.ISLASTSTEP, WF.WORKFLOWSTEPID, P.PATHID")
        sb.AppendLine("FROM WORKFLOWSTEP WF")
        sb.AppendLine("LEFT JOIN PATH P    ON P.TOSTEPID = WF.WORKFLOWSTEPID")
        sb.AppendFormat("WHERE WF.WORKFLOWSTEPID = '{0}' ", strStepID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt.Rows.Count = 0 Then
            Return False
        End If
        Dim dr As DataRow = dt.Rows(0)
        If dr.IsNull("PATHID") Then '没有移动路径
            Exit Function
        End If
        ''表示最后一序或该序没有后续加工工序
        If dr("ISLASTSTEP") = "1" Or dr.IsNull("DEFAULTPATHID") Then
            IsLastStepFinished = True
        End If

    End Function

    ''' <summary>
    ''' 查询批次工艺的父工序是否是最后一道序
    ''' create:Wangjh 20171219
    ''' </summary>
    ''' <param name="strStepID"></param>
    ''' <param name="containerID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function IsLastFinishedOfFaWorkflow(ByVal strStepID As String, ByVal containerID As String) As DataTable
        Dim strSql As String = <string>
                                SELECT (CASE WHEN ws.islaststep=1 OR WS.DEFAULTPATHID IS NULL THEN 1 ELSE 0  END) FAislaststep FROM  WORKFLOWSTEP WS--父工序
                                LEFT JOIN  SUBWORKFLOWCHECKINFO SWC  ON SWC.WORKFLOWID=WS.WORKFLOWID--父工艺关联子工艺校对表
                                LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID=WS.SUBWORKFLOWBASEID
                                LEFT JOIN WORKFLOW W ON  W.WORKFLOWID=NVL(WB.REVOFRCDID,WS.SUBWORKFLOWID)--子工艺
                                LEFT JOIN Workflowstep subws ON subws.workflowid=w.workflowid--子工序
                               </string>
        strSql += String.Format(" WHERE subws.workflowstepid='{0}' AND swc.containerid='{1}'", strStepID, containerID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        IsLastFinishedOfFaWorkflow = dt
    End Function

    ''' <summary>
    ''' 判断批次工序是否是最后序
    '''  create:Wangjh 20180409
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsLastStep(ByVal para As Dictionary(Of String, String)) As Boolean Implements uLMSCommonIBusiness.IsLastStep
        Dim cuIsLast As Boolean = False
        Dim faIsLast As Boolean = False
        cuIsLast = IsLastStepFinished(para("WorkFlowStepID"))
        IsLastStep = cuIsLast
        If cuIsLast = True Then '当前工序是最后一道序时
            Dim dt = IsLastFinishedOfFaWorkflow(para("WorkFlowStepID"), para("ContainerID"))
            If dt.Rows.Count > 0 Then
                If dt.Rows(0)("FAislaststep").ToString = "1" Then '工艺的父工序是最后一道序
                    IsLastStep = True
                ElseIf dt.Rows(0)("FAislaststep").ToString = "0" Then
                    IsLastStep = False
                End If
            End If
        End If
    End Function

    ''' <summary>
    ''' 查询所有看板  Create:YangJiang 20180410
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSubReportKanban() As System.Data.DataSet Implements IBusiness.uLMSCommonIBusiness.GetSubReportKanban
        Dim strSQL = "SELECT RP.REPORTPAGENAME,RP.PAGEURL FROM REPORTPAGE RP WHERE RP.ISLOOKBOARD=1"
        GetSubReportKanban = DatabaseHelper.Query_ReturnDataSet(strSQL)
    End Function

    ''' <summary>
    ''' 更新关闭批次的变号创建的新批次名字 create tianFW 2018年4月18日
    ''' </summary>
    ''' <param name="containerID"></param>
    ''' <param name="containerName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UpdateCloseContianerNewContainerName(ByVal containerID As String, ByVal containerName As String) As Boolean Implements uLMSCommonIBusiness.UpdateCloseContianerNewContainerName
        Dim strsql As String = String.Format("UPDATE CONTAINERCURRENTINFO C SET C.CHANGECONTAINERID = '{0}' WHERE C.CONTAINERID='{1}'", containerName, containerID)
        If DatabaseHelper.ExecuteSql(strsql) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 根据工艺规程编号获取对应的超越单信息 create tianFW 2018年4月24日
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSupPassInfoByWorkflowProcessNO(ByVal ProcessNO As String) As DataSet Implements uLMSCommonIBusiness.GetSupPassInfoByWorkflowProcessNO
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT SPBI.SURPASSBILLINFOID,SPBI.SURPASSBILLNAME,SPBI.SURPASSBILLREVISION,SPBI.PRODUCTNAME,")
        strsql.AppendLine("SPBI.PRODUCTDES,SPBI.FILENO,SPBI.PROCESSNO,SPBI.FACTORYNAME,SPBI.CONTAINERNAME,SPBI.EFFECTIVE")
        strsql.AppendFormat(" FROM SURPASSBILLINFO SPBI WHERE SPBI.PROCESSNO='{0}'", ProcessNO)
        Dim sumContainer = DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
        If sumContainer.Rows.Count = 0 Then
            Return New DataSet
        End If
        strsql.Clear()
        strsql.AppendLine("SELECT SBD.SURPASSBILLINFOID, SBD.SURPASSTYPE, SBD.SURPASSOP, SBD.REMARK")
        strsql.AppendLine("FROM SURPASSBILLDETAIL SBD")
        Dim SupPassBillInfoIDs As String = ""
        For Each dr As DataRow In sumContainer.Rows
            If SupPassBillInfoIDs <> "" Then
                SupPassBillInfoIDs += " OR "
            End If
            SupPassBillInfoIDs += String.Format(" SBD.SURPASSBILLINFOID='{0}'", dr("SURPASSBILLINFOID"))
        Next
        strsql.AppendFormat(" WHERE {0}", SupPassBillInfoIDs)
        Dim sonContainer = DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
        Dim ds As New DataSet
        ds.Tables.Add(sumContainer)
        ds.Tables(0).TableName = "sumContainer"
        ds.Tables.Add(sonContainer)
        ds.Tables(1).TableName = "sonContainer"
        ds.Relations.Add("SumContainer",
        New DataColumn() {ds.Tables(0).Columns("SURPASSBILLINFOID")},
        New DataColumn() {ds.Tables(1).Columns("SURPASSBILLINFOID")})
        GetSupPassInfoByWorkflowProcessNO = ds
    End Function

    ''' <summary>
    ''' Add by Yuxj20180328获取装试发动机工艺路线
    ''' Modify by Yuxj20180911增加workflowid
    ''' </summary>
    ''' <param name="FlowName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetEngineWorkFlow(ByVal FlowName As String) As DataTable Implements uLMSCommonIBusiness.GetEngineWorkFlow
        Dim sb As New StringBuilder
        sb.AppendLine(" SELECT wfs.workflowstepid,wfs.workflowstepname,wfs.sequence,wfs.workflowid, wf.workflowrevision FROM workflowstep wfs ")
        sb.AppendLine(" LEFT JOIN workflow wf ON wfs.workflowid=wf.workflowid ")
        sb.AppendLine(" LEFT JOIN workflowbase wfb ON wf.workflowbaseid=wfb.workflowbaseid ")
        sb.AppendFormat(" WHERE wfb.workflowname='{0}' ", FlowName)
        sb.AppendLine(" ORDER BY wfs.sequence ASC")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        Return dt
    End Function

    ''' <summary>
    ''' 从Container和enginepartplan 获取批次最大序号
    ''' Add by Yuxj20180423
    ''' </summary>
    ''' <param name="strPrefix">批次名称</param>
    ''' <param name="numberLength">序号长度</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetNewContainerPlanNextIndex(ByVal strPrefix As String, ByVal numberLength As Integer) As Integer Implements IBusiness.uLMSCommonIBusiness.GetNewContainerPlanNextIndex

        Dim strContianerName As String = String.Empty
        Dim strContianerPlan As String = String.Empty
        GetNewContainerPlanNextIndex = 0
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT max(C.CONTAINERNAME) CONTAINERNAME FROM CONTAINER C")
        sb.AppendFormat(" WHERE C.CONTAINERNAME LIKE '{0}{1}' AND C.STATUS<>'0'", strPrefix, String.Empty.PadLeft(numberLength, "_"))
        Dim DTContainer As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        sb.Clear()
        sb.AppendLine("SELECT max(C.CONTAINERNAME) CONTAINERNAME FROM enginepartplan C")
        sb.AppendFormat(" WHERE C.CONTAINERNAME LIKE '{0}{1}' ", strPrefix, String.Empty.PadLeft(numberLength, "_"))
        Dim DTPlan As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)

        If DTContainer.Rows.Count = 0 And DTPlan.Rows.Count = 0 Then
            Exit Function
        End If

        If DTContainer.Rows.Count > 0 Then
            strContianerName = DTContainer.Rows(0)("CONTAINERNAME").ToString
        End If

        If DTPlan.Rows.Count > 0 Then
            strContianerPlan = DTPlan.Rows(0)("CONTAINERNAME").ToString
        End If

        If strContianerPlan > strContianerName Then
            strContianerName = strContianerPlan
        End If

        strContianerName = strContianerName.Replace(strPrefix, "")
        If strContianerName.Length < numberLength Then
            Exit Function
        End If

        Dim array As String = strContianerName.Substring(0, numberLength)
        Dim intarray As Integer = 0

        If Integer.TryParse(array, intarray) Then
            If intarray > GetNewContainerPlanNextIndex Then
                GetNewContainerPlanNextIndex = intarray
            End If
        End If

    End Function

    ''' <summary>
    ''' 根据产品和分厂查询工艺路线（分厂可能是主工艺的分厂或子工艺的分厂）
    '''add:Wangjh 20180607
    ''' </summary>
    ''' <param name="strProductID"></param>
    ''' <param name="strFactoryID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowByProductID(ByVal strProductID As String, ByVal strFactoryID As String) As DataTable Implements uLMSCommonIBusiness.GetWorkFlowByProductID
        Dim sb As New StringBuilder
        sb.AppendLine("    SELECT WF.WORKFLOWID,WF.WORKFLOWBASEID ,WFB1.WORKFLOWNAME || ':' || WF.WORKFLOWREVISION || '(' || WF.WORKFLOWTYPE || ')' WORKFLOWNAME,T.PRODUCTID, WF.FACTORYID")
        sb.AppendLine("      FROM PRODUCT T")
        sb.AppendLine("      LEFT JOIN WORKFLOWBASE WFB   ON WFB.WORKFLOWBASEID = T.WORKFLOWBASEID")
        sb.AppendLine("      LEFT JOIN WORKFLOW WF    ON WF.WORKFLOWID = NVL(WFB.REVOFRCDID, T.WORKFLOWID)")
        sb.AppendLine("      LEFT JOIN WORKFLOWBASE WFB1     ON WFB1.WORKFLOWBASEID = WF.WORKFLOWBASEID ")
        sb.AppendLine("  LEFT JOIN Workflowstep ws ON ws.workflowid=WF.workflowid")
        sb.AppendLine(" LEFT JOIN Workflowbase subwb ON subwb.workflowbaseid=ws.subworkflowbaseid")
        sb.AppendLine(" LEFT JOIN workflow subw ON subw.workflowid=NVL(subwb.revofrcdid,ws.subworkflowid)")
        sb.AppendFormat(" WHERE T.PRODUCTID = '{0}' AND (WF.FACTORYID='{1}' OR SUBW.FACTORYID='{1}')", strProductID, strFactoryID)
        sb.AppendLine("  GROUP BY WF.WORKFLOWID,WF.WORKFLOWBASEID ,WFB1.WORKFLOWNAME,WF.WORKFLOWREVISION , WF.WORKFLOWTYPE,T.PRODUCTID, WF.FACTORYID")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString) '默认的
        Dim revofrcdid As String = "" '默认版本的工艺ID
        If dt.Rows.Count > 0 Then
            revofrcdid = dt.Rows(0)("WORKFLOWID")
        End If
        Dim strSql = "SELECT T.WORKFLOWID,T.WORKFLOWBASEID,  WFB.WORKFLOWNAME || ':' || T.WORKFLOWREVISION || '(' || T.WORKFLOWTYPE || ')' WORKFLOWNAME,T.PRODUCTID, T.FACTORYID" &
                    " FROM WORKFLOW T" &
                    " LEFT JOIN WORKFLOWBASE WFB ON WFB.WORKFLOWBASEID = T.WORKFLOWBASEID " &
                    " LEFT JOIN Workflowstep ws ON ws.workflowid=t.workflowid" &
                    " LEFT JOIN Workflowbase subwb ON subwb.workflowbaseid=ws.subworkflowbaseid" &
                    " LEFT JOIN workflow subw ON subw.workflowid=NVL(subwb.revofrcdid,ws.subworkflowid) "
        strSql += String.Format(" WHERE T.PRODUCTID = '{0}' AND (T.FACTORYID='{1}' OR SUBW.FACTORYID='{1}')", strProductID, strFactoryID)
        strSql += " GROUP BY T.WORKFLOWID,T.WORKFLOWBASEID,  WFB.WORKFLOWNAME,T.WORKFLOWREVISION, T.WORKFLOWTYPE,T.PRODUCTID, T.FACTORYID "
        Dim dt2 As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
        For Each row As DataRow In dt2.Rows
            If revofrcdid = row("WORKFLOWID").ToString Then
                Continue For
            End If
            dt.ImportRow(row)
        Next
        dt.AcceptChanges()
        If dt Is Nothing Then
            GetWorkFlowByProductID = New DataTable
        Else
            GetWorkFlowByProductID = dt
        End If
    End Function

    ''' <summary>
    ''' 获取本分厂下所有的班 add YangJiang 20180620
    ''' </summary>
    ''' <param name="strFactoryID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetShiftByFactoryID(ByVal strFactoryID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetShiftByFactoryID
        Dim strSQL As New StringBuilder
        strSQL.AppendFormat("SELECT * FROM shift s WHERE s.factoryid='{0}'", strFactoryID)
        Dim dt = DatabaseHelper.Query_ReturnDatTable(strSQL.ToString)
        If dt Is Nothing Then
            GetShiftByFactoryID = New DataTable
        Else
            GetShiftByFactoryID = dt
        End If
    End Function

    ''' <summary>
    ''' 获取本分厂下所有的班组 add YangJiang 20180620
    ''' </summary>
    ''' <param name="strFactoryID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTeamByFactoryID(ByVal strFactoryID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetTeamByFactoryID
        Dim strSQL As New StringBuilder
        strSQL.AppendFormat("SELECT * FROM team t WHERE t.factoryid='{0}'", strFactoryID)
        Dim dt = DatabaseHelper.Query_ReturnDatTable(strSQL.ToString)
        If dt Is Nothing Then
            GetTeamByFactoryID = New DataTable
        Else
            GetTeamByFactoryID = dt
        End If
    End Function

    ''' <summary>
    ''' 判断该分厂的班、组维护属性是否为'是' add YangJiang 20180620
    ''' </summary>
    ''' <param name="strFactoryID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTeamOrShiftByFactoryID(ByVal strFactoryID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetTeamOrShiftByFactoryID
        Dim strSQL As New StringBuilder
        strSQL.AppendLine("SELECT u.attributevalue FROM factory f LEFT JOIN Userattribute u ON u.parentid=f.factoryid")
        strSQL.AppendFormat(" WHERE f.factoryid='{0}'AND u.userattributename='班、组维护'", strFactoryID)
        Dim dt = DatabaseHelper.Query_ReturnDatTable(strSQL.ToString)
        If dt Is Nothing Then
            GetTeamOrShiftByFactoryID = New DataTable
        Else
            GetTeamOrShiftByFactoryID = dt
        End If
    End Function

    ''' <summary>
    ''' 查询该工区下不属于任何班组的人员 add YangJiang 20180622
    ''' </summary>
    ''' <param name="strWorkcenterID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEmployeeNoTeamByWorkcenterID(ByVal strWorkcenterID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetEmployeeNoTeamByWorkcenterID
        Dim strSQL As New StringBuilder
        strSQL.AppendLine(" SELECT * FROM employee e")
        strSQL.AppendLine(" LEFT JOIN Sessionvalues sv ON sv.employeeid=e.employeeid")
        strSQL.AppendLine(" LEFT JOIN teamemployee te ON te.employeeid=e.employeeid")
        strSQL.AppendLine(" LEFT JOIN team t ON t.teamid=te.teamid")
        strSQL.AppendFormat("  WHERE t.teamid IS NULL AND sv.workcenterid='{0}'", strWorkcenterID)
        Dim dt = DatabaseHelper.Query_ReturnDatTable(strSQL.ToString)
        If dt Is Nothing Then
            GetEmployeeNoTeamByWorkcenterID = New DataTable
        Else
            GetEmployeeNoTeamByWorkcenterID = dt
        End If
    End Function

    ''' <summary>
    ''' 查询该班下不属于任何组的人员 add YangJiang 20180622
    ''' </summary>
    ''' <param name="strShiftID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEmployeeNoTeamByShiftID(ByVal strShiftID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetEmployeeNoTeamByShiftID
        Dim strSQL As New StringBuilder
        strSQL.AppendLine(" SELECT * FROM employee e")
        strSQL.AppendLine(" LEFT JOIN shift s ON e.shiftid=s.shiftid")
        strSQL.AppendLine("  LEFT JOIN teamemployee te ON te.employeeid=e.employeeid")
        strSQL.AppendLine(" LEFT JOIN team t ON t.teamid=te.teamid")
        strSQL.AppendFormat("  WHERE t.teamid IS NULL AND s.shiftid='{0}'", strShiftID)
        Dim dt = DatabaseHelper.Query_ReturnDatTable(strSQL.ToString)
        If dt Is Nothing Then
            GetEmployeeNoTeamByShiftID = New DataTable
        Else
            GetEmployeeNoTeamByShiftID = dt
        End If
    End Function

    ''' <summary>
    ''' 更新人员信息 add YangJiang 20180625
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UpdateEmployeeInfo(ByVal para As Dictionary(Of String, String), ByVal dt As DataTable, ByVal strInfo As String) As Boolean Implements IBusiness.uLMSCommonIBusiness.UpdateEmployeeInfo
        UpdateEmployeeInfo = False
        Dim strSQL As New StringBuilder
        If para.ContainsKey("WorkcenterID") Then
            'Modify by Yuxj20190308 sessionvalues para("WorkCenterID")->para("WorkcenterID")
            strSQL.AppendFormat("update sessionvalues set workcenterid='{0}' where employeeid='{1}'", para("WorkcenterID"), para("EmployeeID"))
            If DatabaseHelper.ExecuteSql(strSQL.ToString) > 0 Then
                UpdateEmployeeInfo = True
            End If
        End If
        If para.ContainsKey("ShiftID") Then
            strSQL.AppendFormat("update employee set shiftid='{0}' where employeeid='{1}'", para("ShiftID"), para("EmployeeID"))
            If DatabaseHelper.ExecuteSql(strSQL.ToString) > 0 Then
                UpdateEmployeeInfo = True
            End If
        End If

        If para.ContainsKey("TeamID") Then
            Dim UserName As String = para("UserName")
            Dim Password As String = para("Password")
            Dim strTxnDocName, strTxnName As String
            strTxnDocName = "TeamMaintDoc"
            strTxnName = "TeamMaint"
            Dim DataEntityList As New List(Of ClientAPIEntity)
            DataEntityList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("TeamName"), ""))

            Dim List_Emp As New Dictionary(Of Integer, String)
            For i = 0 To dt.Rows.Count - 1
                List_Emp.Add(i, dt(i)("EmployeeName"))
            Next
            DataEntityList.Add(New ClientAPIEntity("Employee", InputTypeEnum.Details, DataTypeEnum.NamedObjectList, List_Emp, "", para("EmployeeCount")))

            Dim api As New CamstarClientAPI(UserName, Password)
            UpdateEmployeeInfo = api.UpdateModelByStandard(strTxnDocName, strTxnName, para("TeamName"), "", DataEntityList, strInfo)
        End If

    End Function

    ''' <summary>
    ''' 更新班所属工区 add YangJiang 20180625
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UpdateShiftByShiftID(ByVal para As Dictionary(Of String, String)) As Boolean Implements IBusiness.uLMSCommonIBusiness.UpdateShiftByShiftID
        Dim strSQL As New StringBuilder
        strSQL.AppendFormat("update shift set workcenterid='{0}' where shiftid='{1}'", para("WorkcenterID"), para("ShiftID"))
        Dim count = DatabaseHelper.ExecuteSql(strSQL.ToString)
        If count > 0 Then
            UpdateShiftByShiftID = True
        Else
            UpdateShiftByShiftID = False
        End If
    End Function

    ''' <summary>
    ''' 更新班组/组信息 add YangJiang 20180625
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UpdateTeamInfo(ByVal para As System.Collections.Generic.Dictionary(Of String, String)) As Boolean Implements IBusiness.uLMSCommonIBusiness.UpdateTeamInfo
        Dim strSQL As New StringBuilder
        If para.ContainsKey("WorkCenterID") Then
            strSQL.AppendFormat("update team set workcenterid='{0}' where teamid='{1}'", para("WorkCenterID"), para("TeamID"))
        End If
        If para.ContainsKey("ShiftID") Then
            strSQL.AppendFormat("update team set shiftid='{0}' where teamid='{1}'", para("ShiftID"), para("TeamID"))
        End If
        Dim count = DatabaseHelper.ExecuteSql(strSQL.ToString)
        If count > 0 Then
            UpdateTeamInfo = True
        Else
            UpdateTeamInfo = False
        End If
    End Function

    ''' <summary>
    ''' 获取所选产品版本的材质信息 modify:Wangjh 20190116增加锻铸件类型查询
    ''' </summary>
    ''' <param name="productname"></param>
    ''' <param name="revision"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>Modify YangJiang 20180627 LEFT JOIN producttype pt ON pt.producttypeid=p.producttypeid,LEFT JOIN materialtype mt ON mt.materialtypeid=p.materialtypeid
    Public Function GetMaterialByProduct(ByVal productname As String, ByVal revision As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetMaterialByProduct
        Dim strSql As String = "SELECT MaterialStatus,MaterialSize,MaterialSpecification,MaterialTrademark,Materialcode,pt.producttypename,p.firstusedproduct,p.technicalconditions" & vbCrLf & _
                                ",p.materialrequest,mt.materialtypename,p.description,DECODE(ut.attributevalue,'是','是','否') IsDuanzhu,p.charactertype,ct.lastchangedate FROM product p" & vbCrLf & _
                               "LEFT JOIN productbase pb ON pb.productbaseid=p.productbaseid OR pb.revofrcdid=p.productid" & vbCrLf & _
                               "LEFT JOIN producttype pt ON pt.producttypeid=p.producttypeid" & vbCrLf & _
                               "LEFT JOIN materialtype mt ON mt.materialtypeid=p.materialtypeid" & vbCrLf & _
                               "LEFT JOIN Changestatus ct ON ct.parentid = p.productid" & vbCrLf & _
                               " LEFT JOIN Userattribute ut ON ut.parentid=p.productid AND ut.userattributename='锻铸件类型' " &
                               "WHERE pb.productname='" & productname & "' and p.productrevision='" & revision & "' "
        Dim DT As DataTable = dal.StandardGetDataTable(strSql)

        Return DT
    End Function

    ''' <summary>
    ''' 获取工艺路线所属工艺列表 create tianFW 2017/09/11
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' Modify by YangJiang 20180614  S.SPECNO->,NVL(s.specno,SUBSTR(wt.workflowstepname,0,INSTR(wt.workflowstepname,'-','1')-1)) SPECNO
    ''' add YangJiang 20180627 DECODE(S.ISKEY,1,'是','否') isKey  'add YangJiang 20180614 查找工序号
    ''' </remarks>
    Public Function GetWorkFlowSetpsViewDetailByWorkflowID(ByVal para As Dictionary(Of String, String)) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowSetpsViewDetailByWorkflowID
        Dim sb As New StringBuilder
        sb.AppendLine(<string>SELECT DECODE(S.ISKEY,1,'是','否') isKey,WT.WORKFLOWSTEPID, WT.WORKFLOWSTEPNAME, WT.SEQUENCE,S.SPECREVISION,
WT.DESCRIPTION,S.SPECID,SB.SPECNAME,DECODE(wt.wipmsglabel,NULL,'Spec','SubWorkflow') WFSTYPE,
WT.ISLASTSTEP,B.BOMID,wc.workcentername,t.teamname,f.factoryname,s.factoryid,wt.controlcode,s.iscooperation,s.isspotcheck,
s.lastcheck,NVL(s.specno,SUBSTR(wt.workflowstepname,0,INSTR(wt.workflowstepname,'-','1')-1)) SPECNO,s.parentspecno,ct.lastchangedate,
nvl(wf2.workflowid,WF.WORKFLOWID) workflowid,nvl( wf2.workflowbaseid,wf.workflowbaseid) workflowbaseid,nvl(wf2.workflowrevision,WF.WORKFLOWREVISION) WORKFLOWREVISION,
nvl( wb2.workflowname,WB.WORKFLOWNAME) WORKFLOWNAME,s.commonsubworkflow
FROM WORKFLOWSTEP WT

LEFT JOIN SPECBASE SB_ ON SB_.SPECBASEID = NVL(WT.SPECBASEID, WT.SUBWORKFLOWBASEID)
LEFT JOIN SPEC S ON S.SPECID = NVL(SB_.REVOFRCDID,WT.SPECID)
LEFT JOIN SPECBASE SB ON SB.SPECBASEID = S.SPECBASEID

--正常子工艺
LEFT JOIN V_STEPRELEVANTTOSONWF sbsk ON sbsk.workflowstepid = wt.workflowstepid 
LEFT JOIN WORKFLOW WF ON WF.WORKFLOWID = sbsk.sonworkflowid
LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID = WF.WORKFLOWBASEID
--通用子工艺的情况
left join workflowbase wb2 on wb2.workflowname='WF-'||s.commonsubworkflow
left join workflow wf2 on wf2.process_no=s.commonsubworkflow and wf2.workflowid=wb2.revofrcdid

LEFT JOIN BOM B ON B.WORKFLOWID = WF.WORKFLOWID
LEFT JOIN Changestatus ct ON ct.parentid = DECODE(wf.workflowid,NULL,S.SPECID,wf.workflowid)
LEFT JOIN workcenter wc on wc.workcenterid = wt.workcenterid
LEFT JOIN team t on t.teamid = wt.teamid
LEFT JOIN SPECBASE SB1 ON SB1.SPECBASEID = WT.SPECBASEID
LEFT JOIN SPEC S1 ON S1.SPECID = NVL(SB1.REVOFRCDID,WT.SPECID)
LEFT JOIN factory f on f.factoryid = S1.factoryid </string>)
        sb.AppendFormat(" WHERE WT.SEQUENCE IS NOT NULL AND WT.WORKFLOWID= '{0}'", para("WorkflowID"))
        If para.Keys.Contains("ChildWorkflow") Then
            sb.AppendLine("AND wt.wipmsglabel IS NOT NULL")
        End If
        sb.AppendLine("ORDER BY WT.SEQUENCE")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        dt.Columns.Add("workflowstepnameno")
        dt.Columns.Add("dclaststep")
        dt.Columns.Add("ChildWorkflow")
        dt.Columns.Add("stepType") '工序类型-固定外委、固定转工、检验工序、特殊过程
        Dim dtWorkflow As DataTable = GetWorkflowInfoByID(para("WorkflowID")).DBTable
        Dim strWorkflowFactory As String = para("userFactoryID") '如果工艺路线上没有定义工厂，就使用登录用户的工厂ID
        If dtWorkflow.Rows.Count > 0 Then
            If dtWorkflow.Rows(0)("factoryid").ToString() <> "" Then
                strWorkflowFactory = dtWorkflow.Rows(0)("factoryid").ToString() '获取工艺workflow上的工厂
            End If
        End If

        For i As Integer = 0 To dt.Rows.Count - 1
            Dim namestr As String = dt.Rows(i)("workflowstepname").ToString()
            Dim strArray As String() = namestr.Split("-")
            If strArray.Length >= 2 Then
                dt.Rows(i)("workflowstepnameno") = strArray(strArray.Length - 2)
                'dt.Rows(i)("workflowstepname") = strArray(strArray.Length - 1)'modify tianFW 2017/10/25 屏蔽
            End If
            If dt.Rows(i)("islaststep").ToString() = "0" Then
                dt.Rows(i)("dclaststep") = " "
            Else
                dt.Rows(i)("dclaststep") = "是"
            End If

            If dt.Rows(i)("WFSTYPE") = "SubWorkflow" Then
                If dt.Rows(i).IsNull("WORKFLOWNAME") Then
                    dt.Rows(i)("ChildWorkflow") = "子工艺"
                Else
                    dt.Rows(i)("ChildWorkflow") = dt.Rows(i)("WORKFLOWNAME") & ":" & dt.Rows(i)("WORKFLOWREVISION")
                    If Not String.IsNullOrWhiteSpace(dt.Rows(i)("commonsubworkflow").ToString) Then
                        dt.Rows(i)("ChildWorkflow") += "|通用"
                    End If
                End If
            End If

            dt.Rows(i)("steptype") = "普通工序"
            If dt.Rows(i)("controlcode").ToString() = "LY05" Then
                dt.Rows(i)("stepType") = "固定外委"
            ElseIf dt.Rows(i)("controlcode").ToString() = "LY07" Then
                dt.Rows(i)("stepType") = "虚拟工序"
            ElseIf dt.Rows(i)("factoryid").ToString() <> strWorkflowFactory Then
                If dt.Rows(i)("factoryid").ToString() = "" Then
                    dt.Rows(i)("stepType") = "工序未维护分厂"
                Else
                    dt.Rows(i)("stepType") = "固定转工"
                End If
            End If
            If dt.Rows(i)("lastCheck").ToString() = "1" Then
                dt.Rows(i)("stepType") = dt.Rows(i)("stepType") & "|检序"
            End If
            If dt.Rows(i)("isspotcheck").ToString() = "1" Then
                dt.Rows(i)("stepType") = dt.Rows(i)("stepType") & "|特殊"
            End If
        Next
        Return dt
    End Function

    ''' <summary>
    ''' 根据ID获取workflow信息
    ''' </summary>
    ''' <param name="strID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkflowInfoByID(ByVal strID As String) As uMESProcessResult Implements IBusiness.uLMSCommonIBusiness.GetWorkflowInfoByID
        Dim strQuery As String = "SELECT w.factoryid,w.firststepid,w.documentsetid,w.workcenterid,w.productid,wb.workflowname,w.workflowrevision,w.description,w.workflowid FROM workflow w" & vbCrLf & _
                                "LEFT JOIN workflowbase wb ON wb.workflowbaseid = w.workflowbaseid" & vbCrLf & _
                                "WHERE wb.workflowid = '" & strID & "'"
        Dim result As New uMESProcessResult
        Try
            Dim DT As DataTable = dal.GetWorkFlowInfoByName(strQuery)
            result.Result = True
            result.DBTable = DT
        Catch ex As Exception
            result.Result = False
            result.Message = ex.Message
        End Try
        Return result
    End Function

    ''' <summary>
    ''' 获取配套表BOM
    ''' </summary>
    ''' <param name="bomid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetBOM(ByVal bomid As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetBOM
        Dim strSql As String
        'Modify by tianFW 添加bom Notes查询以及BomName、StepInfoName SPECTYPENAME stepinfodesc查询 2018年4月23日
        'modify by tianFW 修改Spec信息的查询 添加s.specno查询 2018年6月4日 
        '添加pm.materialtxnlogic IssueControl,pm.referencedesignator referencedes,s.specrevision,b.bomrevision查询 2018年7月31日 tianFW
        'Modify by Yuxj20180718增加p.description pdesc
        strSql = "SELECT pb.productname,p.productid,sb.specname,s.specno,ST.SPECTYPENAME,pb.productname||':'||p.productrevision productinfo,s.specrevision," & vbCrLf & _
                "pm.materialtxnlogic IssueControl,pm.referencedesignator referencedes,pm.qtyrequired,pm.qty2required,p.productrevision,p.description pdesc," & vbCrLf & _
                "B.NOTES,BB.BOMNAME,PM.STEPINFOID,SIOB.STEPINFONAME,PM.BIGSMALLPART,sio.stepno||'-'||sio.description stepinfodesc,pm.productmateriallistitemname,b.bomrevision" & vbCrLf & _
                "FROM productmateriallistitem pm" & vbCrLf & _
                "LEFT JOIN productbase pb1 ON pb1.productbaseid=pm.productbaseid  " & vbCrLf & _
                "LEFT JOIN product p ON p.productid=NVL(pb1.revofrcdid,pm.productid) " & vbCrLf & _
                "LEFT JOIN productbase pb ON pb.productbaseid=p.productbaseid " & vbCrLf & _
                "LEFT JOIN specbase sb1 ON sb1.specbaseid=pm.specbaseid" & vbCrLf & _
                "LEFT JOIN spec s ON s.specid=NVL(sb1.revofrcdid,pm.specid) " & vbCrLf & _
                "LEFT JOIN specbase sb ON sb.specbaseid=s.specbaseid " & vbCrLf & _
                "LEFT JOIN BOM B ON B.BOMID = PM.BOMID" & vbCrLf & _
                "LEFT JOIN BOMBASE BB ON BB.BOMBASEID = B.BOMBASEID" & vbCrLf & _
                "LEFT JOIN STEPINFO SIO ON SIO.STEPINFOID = PM.STEPINFOID" & vbCrLf & _
                "LEFT JOIN WORKFLOWSTEP WS ON SIO.Workflowstepid = WS.Workflowstepid" & vbCrLf & _
                "LEFT JOIN STEPINFOBASE SIOB ON SIOB.STEPINFOBASEID = SIO.STEPINFOBASEID" & vbCrLf & _
                "LEFT JOIN SPECTYPE ST ON ST.SPECTYPEID = SIO.SPECTYPEID " & vbCrLf & _
                "WHERE pm.bomid='" & bomid & "'"
        strSql += "ORDER BY WS.SEQUENCE,sio.STEPNO,sio.STEPSEQ "
        Dim DT As DataTable = dal.StandardGetDataTable(strSql)
        DT.Columns.Add("specnameno")
        'DT.Columns.Add("productinfo")‘屏蔽 tianFW 2018年6月4日
        For i As Integer = 0 To DT.Rows.Count - 1
            If Not DT.Rows(i).IsNull("specno") Then
                DT.Rows(i)("specnameno") = DT.Rows(i)("specno")
            Else
                Dim namestr As String = DT.Rows(i)("specname").ToString()
                Dim strArray As String() = namestr.Split("-")
                If strArray.Length >= 2 Then
                    'DT.Rows(i)("specname") = strArray(strArray.Length - 1)'modify tianFW 2017/10/25 屏蔽
                    DT.Rows(i)("specnameno") = Convert.ToInt32(strArray(strArray.Length - 2))
                End If
            End If
            'DT.Rows(i)("productinfo") = DT.Rows(i)("productname") + ":" + DT.Rows(i)("productrevision") modify tianFW 2018/06/04 屏蔽
        Next
        Dim tmpRows As DataRow() = DT.Select("", "specnameno asc")
        Dim dtq As DataTable = DT.Clone()
        For Each row1 As DataRow In tmpRows
            dtq.ImportRow(row1)
        Next
        Return dtq
    End Function

    ''' <summary>
    ''' 根据bomname获取bom信息 create by tianFW 2018年9月28日
    ''' </summary>
    ''' <param name="bomname"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetBomInfoByName(ByVal bomname As String) As DataTable Implements uLMSCommonIBusiness.GetBomInfoByName
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT bb.bomname,b.bomid,b.bomrevision,bb.revofrcdid FROM bombase bb")
        strsql.AppendLine("LEFT JOIN bom b ON b.bombaseid = bb.bombaseid")
        strsql.AppendFormat(" WHERE bb.bomname='{0}'", bomname)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取工艺版本制定的工艺员及工艺所属分厂 add YangJiang 20180627 modify：Wangjh 20190116 查询工艺所有 'yuxj20220810 增加useQuota
    ''' yuxj20221011增加展示工艺对应的默认件号
    ''' </summary>
    ''' <param name="strWorkFlowID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowEmpAndFactoryByWorkFlowID(ByVal strWorkFlowID As String) As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowEmpAndFactoryByWorkFlowID
        Dim strSQL As String =
            <string>
                SELECT e.fullname,e.employeename,wf.*,f.factoryid,f.factoryname,ct.lastchangedate,wf.useQuota,
                       nvl2(pb.productname,pb.productname||':'||p.productrevision,null) defaultproduct 
                 FROM Workflow wf
                LEFT JOIN  employee e  ON wf.zgemployeeid=e.employeeid
                LEFT JOIN factory f ON f.factoryid=wf.factoryid
                LEFT JOIN product p on p.productid=wf.productid
                LEFT JOIN productbase pb on pb.productbaseid=p.productbaseid
                LEFT JOIN Changestatus ct ON ct.parentid = wf.workflowid
            </string>
        strSQL += "where wf.workflowid='" & strWorkFlowID & "'"
        GetWorkFlowEmpAndFactoryByWorkFlowID = DatabaseHelper.Query_ReturnDatTable(strSQL)
    End Function

    ''' <summary>
    ''' 获取工种信息 create by tianFW 2018年7月23日
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetOperationInfo() As DataTable Implements uLMSCommonIBusiness.GetOperationInfo
        Dim strsql As String = "SELECT op.operationname,op.operationid FROM operation op ORDER BY op.operationname"
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function

    ''' <summary>
    ''' 创建工艺路线 create by Yangsj 20180702
    ''' </summary>
    ''' <param name="para"></param>
    ''' <param name="dtStepList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function SaveWorkflow(ByVal para As Dictionary(Of String, String), ByVal dtStepList As DataTable) As ResultStatus Implements uLMSCommonIBusiness.SaveWorkflow
        Dim strInfo As String = ""
        SaveWorkflow = New ResultStatus
        Dim m_DataList As New List(Of ClientAPIEntity)
        m_DataList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkflowName"), ""))
        m_DataList.Add(New ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, para("Rev"), ""))
        m_DataList.Add(New ClientAPIEntity("Description", InputTypeEnum.Details, DataTypeEnum.DataField, para("Description"), ""))
        m_DataList.Add(New ClientAPIEntity("Notes", InputTypeEnum.Details, DataTypeEnum.DataField, para("Notes"), ""))
        If para.ContainsKey("Ly2Modle_node") Then
            m_DataList.Add(New ClientAPIEntity("Ly2Modle_node", InputTypeEnum.Details, DataTypeEnum.DataField, para("Ly2Modle_node"), ""))
        End If

        'Modify by Yuxj20180731
        If para.ContainsKey("PhaseNode") Then
            m_DataList.Add(New ClientAPIEntity("PhaseNode", InputTypeEnum.Details, DataTypeEnum.DataField, para("PhaseNode"), ""))
        End If

        'Modify by Yuxj20181226
        If para.ContainsKey("Process_No") Then
            m_DataList.Add(New ClientAPIEntity("Process_No", InputTypeEnum.Details, DataTypeEnum.DataField, para("Process_No"), ""))
        End If

        If para.ContainsKey("ProductName") Then
            m_DataList.Add(New ClientAPIEntity("Product", InputTypeEnum.Details, DataTypeEnum.RevisionedObjectField, para("ProductName"), para("ProductRev")))
        End If
        m_DataList.Add(New ClientAPIEntity("Factory", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("Factory"), ""))
        If para.ContainsKey("WorkFlowType") Then
            m_DataList.Add(New ClientAPIEntity("WorkFlowType", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkFlowType"), ""))
        End If

        'Modify by zhangrj20250620
        If para.ContainsKey("WorkflowType2") Then '工艺类型2
            m_DataList.Add(New ClientAPIEntity("WorkflowType2", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkflowType2"), ""))
        End If

        'Modify by zhangrj20250620
        If para.ContainsKey("PartRevID") Then '设计图版次
            m_DataList.Add(New ClientAPIEntity("Part_RevID", InputTypeEnum.Details, DataTypeEnum.DataField, para("PartRevID"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("TaskNo") Then '任务号/批次号（工装工具）
            m_DataList.Add(New ClientAPIEntity("TaskNo", InputTypeEnum.Details, DataTypeEnum.DataField, para("TaskNo"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("BjQty") Then '备件数量（工装工具）
            m_DataList.Add(New ClientAPIEntity("BjQty", InputTypeEnum.Details, DataTypeEnum.DataField, para("BjQty"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("Qty") Then '在制数（工装工具）
            m_DataList.Add(New ClientAPIEntity("Qty", InputTypeEnum.Details, DataTypeEnum.DataField, para("Qty"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("WorkCenterName") Then '工区（工装工具）
            m_DataList.Add(New ClientAPIEntity("WorkCenter", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("WorkCenterName"), ""))
        End If

        'Modify by zhangrj20250107
        If para.ContainsKey("MaterialSize") Then '毛料数量（工装工具）
            m_DataList.Add(New ClientAPIEntity("mlsl", InputTypeEnum.Details, DataTypeEnum.DataField, para("MaterialSize"), ""))
        End If

        If para.ContainsKey("ProductFamilyList") Then
            If para.ContainsKey("HaveManyFamily") Then '有多个机型
                If Not String.IsNullOrWhiteSpace(para("ProductFamilyList")) Then
                    Dim ProductFamilyList As New Dictionary(Of Integer, String)
                    Dim FamilyLists As String() = para("ProductFamilyList").Split(";")
                    Dim index As Integer = 0
                    For Each familyStr As String In FamilyLists
                        index += 1
                        ProductFamilyList.Add(index.ToString, familyStr)
                    Next
                    m_DataList.Add(New ClientAPIEntity("ProductFamilyList", InputTypeEnum.Details, DataTypeEnum.NamedObjectList, ProductFamilyList, "", para("FamilyCount")))
                End If
            Else
                If Not String.IsNullOrWhiteSpace(para("ProductFamilyList")) Then
                    Dim ProductFamilyList As New Dictionary(Of Integer, String)
                    ProductFamilyList.Add("1", para("ProductFamilyList"))
                    m_DataList.Add(New ClientAPIEntity("ProductFamilyList", InputTypeEnum.Details, DataTypeEnum.NamedObjectList, ProductFamilyList, "", para("FamilyCount")))
                End If
            End If
        End If

        Dim strWorkflowName As String = para("WorkflowName")
        Dim strRevsion As String = para("Rev")
        Dim serverUser As String = para("UserName")
        Dim serverPassword As String = para("Password")

        Dim api As New CamstarClientAPI(serverUser, serverPassword)

        If para("WorkFlowEditFlag") = "Add" Then
            SaveWorkflow.IsError = Not api.CreateNewWorkflow(strWorkflowName, strRevsion, m_DataList, dtStepList, strInfo)
        ElseIf para("WorkFlowEditFlag") = "Update" Then
            SaveWorkflow.IsError = Not api.UpdateModel("MachineMfgWorkFlowMaint", strWorkflowName, strRevsion, m_DataList, Nothing, strInfo)
        Else
            SaveWorkflow.IsError = Not api.DeleteModel("MachineMfgWorkFlowMaint", strWorkflowName, "", "RO", strInfo)
            'Modify by Yuxj20190319 顺序执行两个API方法，第一个无异常后执行第二个
            If Not SaveWorkflow.IsError Then
                SaveWorkflow.IsError = Not api.CreateNewWorkflow(strWorkflowName, strRevsion, m_DataList, dtStepList, strInfo)
            End If
        End If
        SaveWorkflow.Message = strInfo
    End Function

    ''' <summary>
    ''' 保存工步 create by Yangsj 20180702
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function SaveStepInfo(ByVal para As Dictionary(Of String, String)) As ResultStatus Implements uLMSCommonIBusiness.SaveStepInfo
        Dim strInfo As String = ""
        SaveStepInfo = New ResultStatus
        Dim m_DataList As New List(Of ClientAPIEntity)
        m_DataList.Add(New ClientAPIEntity("Name", InputTypeEnum.Details, DataTypeEnum.DataField, para("StepInfoName"), ""))
        m_DataList.Add(New ClientAPIEntity("Revision", InputTypeEnum.Details, DataTypeEnum.DataField, para("Revision"), ""))
        m_DataList.Add(New ClientAPIEntity("Notes", InputTypeEnum.Details, DataTypeEnum.DataField, para("Notes"), ""))
        m_DataList.Add(New ClientAPIEntity("Description", InputTypeEnum.Details, DataTypeEnum.DataField, para("Description"), ""))
        m_DataList.Add(New ClientAPIEntity("StepNo", InputTypeEnum.Details, DataTypeEnum.DataField, para("SpecNO"), ""))
        m_DataList.Add(New ClientAPIEntity("StepSeq", InputTypeEnum.Details, DataTypeEnum.DataField, para("StepSeq"), ""))
        m_DataList.Add(New ClientAPIEntity("SpecType", InputTypeEnum.Details, DataTypeEnum.NamedObjectField, para("SpecType"), ""))
        m_DataList.Add(New ClientAPIEntity("WorkflowStepID", InputTypeEnum.Details, DataTypeEnum.DataField, para("WorkflowStepID"), ""))
        Dim serverUser As String = para("UserName")
        Dim serverPassword As String = para("Password")
        Dim api As New CamstarClientAPI(serverUser, serverPassword)
        If para("EditFlag") = "Add" Then
            SaveStepInfo.IsError = Not api.CreateModel("StepInfoMaint", m_DataList, Nothing, strInfo)
        ElseIf para("EditFlag") = "Update" Then
            SaveStepInfo.IsError = Not api.UpdateModel("StepInfoMaint", para("StepInfoName"), para("Revision"), m_DataList, Nothing, strInfo)
        ElseIf para("EditFlag") = "Delete" Then
            SaveStepInfo.IsError = Not api.DeleteModel("StepInfoMaint", para("StepInfoName"), "", "RO", strInfo)
        End If

        SaveStepInfo.Message = strInfo
    End Function

    ''' <summary>
    ''' 保存工序 create Yangsj 20180702
    ''' Modify by Yuxj20180827 增加Spec及WorkflowStep  Description记录
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function SaveStep(ByVal para As Dictionary(Of String, String)) As ResultStatus Implements uLMSCommonIBusiness.SaveStep
        Dim strsql As String
        SaveStep = New ResultStatus
        If String.IsNullOrWhiteSpace(para("SpecID")) Then
            SaveStep = CreateSpec(para)
        Else
            strsql = String.Format("UPDATE WORKFLOWSTEP SET WORKFLOWSTEPNAME ='{0}',Description='{1}' WHERE WORKFLOWSTEPID = '{2}'",
                                   para("WorkflowStepName"), para("OPDesc"), para("WorkflowStepID"))
            Dim i As Integer = DatabaseHelper.ExecuteSql(strsql)

            strsql = String.Format("UPDATE SPEC SET SPECNO ='{0}',Description='{1}' WHERE SPECID = '{2}'",
                       para("SpecNO"), para("OPDesc"), para("SpecID"))
            i = DatabaseHelper.ExecuteSql(strsql)
            SaveStep.IsError = If(i = 0, True, False)
        End If
    End Function

    '获取工序类型
    Private Function GetSpecType() As DataTable Implements uLMSCommonIBusiness.GetSpecType
        Dim strsql As String =
        <string>
            SELECT SPECTYPEID, SPECTYPENAME FROM SPECTYPE
        </string>
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function


    ''' <summary>
    ''' 查询发动机 create by Yangsj 20180705
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEngineNO(ByVal para As Dictionary(Of String, String)) As uMESProcessResult Implements uLMSCommonIBusiness.GetEngineNO
        Dim strsql As String =
                   <string>
                             SELECT U.ATTRIBUTEVALUE ENGINENO, PB.PRODUCTNAME,WPF.PRODUCTFAMILYNAME
               FROM MFGORDER M
               LEFT JOIN PRODUCT P1  ON P1.PRODUCTID = M.PRODUCTID
               LEFT JOIN PRODUCTBASE PB on  PB.PRODUCTBASEID=nvl(P1.PRODUCTBASEID,m.PRODUCTBASEID)
               --Modify by Yuxj20180824
               LEFT JOIN product p ON p.productid=NVL(p1.productid,pb.revofrcdid)
               LEFT JOIN WORKFLOW w ON w.WORKFLOWBASEID =p.WORKFLOWBASEID   --add by longb 2023-07-18
               --Modify by Yuxj20180824 LEFT->INNER
               INNER JOIN (SELECT to_char(WM_CONCAT(PF.PRODUCTFAMILYNAME)) PRODUCTFAMILYNAME,   W.WORKFLOWID
                            FROM WORKFLOWPRODUCTFAMILYLIST W
                            LEFT JOIN PRODUCTFAMILY PF  ON PF.PRODUCTFAMILYID = W.PRODUCTFAMILYLISTID
                           GROUP BY W.WORKFLOWID) WPF  ON WPF.WORKFLOWID = DECODE(P.WORKFLOWID,'0000000000000000',w.WORKFLOWID,p.WORKFLOWID) --modify by longb 2023-07-18              
               LEFT JOIN USERATTRIBUTE U   ON U.PARENTID = M.MFGORDERID AND U.USERATTRIBUTENAME = '发动机'               
            </string>
        strsql += String.Format("   WHERE M.FACTORYID = '{0}' AND U.ATTRIBUTEVALUE LIKE '%{1}%' ", para("FactoryID"), para("EngineNo"))
        strsql += " GROUP BY U.ATTRIBUTEVALUE, PB.PRODUCTNAME,WPF.PRODUCTFAMILYNAME "
        Dim paraPage As New uMESPagingDataDTO
        paraPage.CurrentPageIndex = Convert.ToInt32(para("CurrentPageIndex"))
        paraPage.PageSize = Convert.ToInt32(para("PageSize").ToString)
        paraPage.strSQL = strsql.ToString
        '主数据进行分页
        GetEngineNO = DatabaseHelper.RunProcedureForPage(paraPage)

    End Function

    ''' <summary>
    ''' 获取机型列表  Create by Yangsj 20180705
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetProductFamilyByPage(ByVal para As System.Collections.Generic.Dictionary(Of String, String)) As uMESProcessResult Implements IBusiness.uLMSCommonIBusiness.GetProductFamilyByPage
        Dim sb As New StringBuilder
        sb.AppendLine("SELECT PF.PRODUCTFAMILYNAME, PF.PRODUCTFAMILYID FROM PRODUCTFAMILY PF")
        sb.AppendFormat(" WHERE PF.PRODUCTFAMILYNAME LIKE '%{0}%' ", para("FamilyName"))
        sb.AppendLine(" ORDER BY PF.PRODUCTFAMILYNAME") 'add tianFW 2018年3月20日 机型按首字母排序
        Dim paraPage As New uMESPagingDataDTO
        paraPage.CurrentPageIndex = Convert.ToInt32(para("CurrentPageIndex"))
        paraPage.PageSize = Convert.ToInt32(para("PageSize").ToString)
        paraPage.strSQL = sb.ToString
        '主数据进行分页
        GetProductFamilyByPage = DatabaseHelper.RunProcedureForPage(paraPage)
    End Function

    ''' <summary>
    ''' 获取施工工艺列表  Create by Yangsj 20180705
    ''' 增加任务单号显示 Modify by Yuxj20180727
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTempWorkflow(ByVal para As System.Collections.Generic.Dictionary(Of String, String)) As uMESProcessResult Implements IBusiness.uLMSCommonIBusiness.GetTempWorkflow
        Dim strSQL As String =
            <string>
                SELECT WFB.WORKFLOWNAME,WF.LY2MODLE_NODE,WF.LY2MODLE_NODE attributevalue, WF.NOTES, PF.PRODUCTFAMILYNAME, WF.WORKFLOWID, 
                WFPF.CONNUM,WF.WORKFLOWREVISION,ep.containerNo,m.mfgorderid,m.mfgordername,ep.enginecontainerid containerid,p.description,
                wf.process_no,to_char(to_date(wf.process_no,'yyyy/mm/dd hh24:mi:ss'),'yyyy/mm/dd hh24') DispatchDate,
                ec.fullname createfullname,wf.createdatetime,wf.checkdatetime,ech.fullname checkfullname               
                 FROM WORKFLOW WF
                 --添加任务单显示
                 LEFT JOIN enginepartplan ep ON wf.workflowid=ep.workflowid
                 LEFT JOIN product p ON ep.productid=p.productid 
                 LEFT JOIN mfgorder m ON ep.mfgorderid=m.mfgorderid                  
                 LEFT JOIN WORKFLOWBASE WFB ON WF.WORKFLOWBASEID = WFB.WORKFLOWBASEID
                 LEFT JOIN (SELECT COUNT(WORKFLOWID) CONNUM,WORKFLOWID, MAX(PRODUCTFAMILYLISTID) PRODUCTFAMILYLISTID
                              FROM WORKFLOWPRODUCTFAMILYLIST GROUP BY WORKFLOWID) WFPF
                   ON WFPF.WORKFLOWID = WF.WORKFLOWID
                LEFT JOIN PRODUCTFAMILY PF ON PF.PRODUCTFAMILYID = WFPF.PRODUCTFAMILYLISTID
                LEFT JOIN employee ec ON ec.employeeid=wf.createemployeeid
                LEFT JOIN employee ech ON ech.employeeid=wf.checkemployeeid
                WHERE WF.WORKFLOWTYPE = '施工工艺'
            </string>
        'Modify by Yuxj20181218 施工单页面需精确查询？
        If para.ContainsKey("WorkflowName") Then
            strSQL += String.Format(" AND WFB.WORKFLOWNAME  LIKE '%{0}%'", para("WorkflowName"))
        End If

        'Modify by Yuxj20180906
        If para.ContainsKey("EngineNO") Then
            strSQL += String.Format(" AND WF.LY2MODLE_NODE  LIKE '%{0}%'", para("EngineNO"))
        End If

        'Modify by Yuxj20181023
        If para.ContainsKey("MfgOrderName") Then
            strSQL += String.Format(" AND m.MfgOrderName  LIKE '%{0}%'", para("MfgOrderName"))
        End If

        If para.ContainsKey("Status") Then
            If para("Status") = "未使用" Then
                ' Modify by Yuxj20200603 只有校对过的施工单才可分解 and wf.checkemployeeid >'0' 
                strSQL += String.Format(" AND ep.containerName is null and wf.checkemployeeid >'0' ")
            ElseIf para("Status") = "已使用" Then
                strSQL += String.Format(" AND ep.containerName is not null ")
            ElseIf para("Status") = "未校对" Then
                strSQL += String.Format(" AND wf.checkemployeeid is null ")
            End If
        End If

        'Modify by Yuxj20200603增加校对状态
        If para.ContainsKey("CheckStatus") Then
            If para("CheckStatus") = "0" Then
                strSQL += " and wf.checkemployeeid IS NULL "
            Else
                strSQL += " and wf.checkemployeeid >'0' "
            End If
        End If

        Dim paraPage As New uMESPagingDataDTO
        paraPage.CurrentPageIndex = Convert.ToInt32(para("CurrentPageIndex"))
        paraPage.PageSize = Convert.ToInt32(para("PageSize").ToString)
        paraPage.strSQL = strSQL.ToString
        '主数据进行分页
        GetTempWorkflow = DatabaseHelper.RunProcedureForPage(paraPage)
    End Function


    ''' <summary>
    ''' 查询工艺信息
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkflowinfo(ByVal para As Dictionary(Of String, String)) As uMESProcessResult Implements uLMSCommonIBusiness.GetWorkflowinfo
        Dim strSql As String = <string>
                                    SELECT DISTINCT wb.workflowname,w.workflowrevision,pb.productname,p.productrevision,p.productid,w.workflowid,pf.productfamilyname,pf.productfamilyid,w.notes FROM workflow w 
         LEFT JOIN workflowbase wb ON wb.workflowbaseid=w.workflowbaseid
         LEFT JOIN WORKFLOWPRODUCTFAMILYLIST wt ON wt.workflowid=w.workflowid
         LEFT JOIN PRODUCTFAMILY PF ON PF.PRODUCTFAMILYID = wt.PRODUCTFAMILYLISTID
         LEFT JOIN product p ON p.productid=w.productid
         LEFT JOIN productbase pb ON pb.productbaseid=p.productbaseid
         WHERE 1=1
                               </string>.Value
        If para.ContainsKey("WorkflowName") Then
            strSql += String.Format(" AND WB.WORKFLOWNAME  LIKE '%{0}%'", para("WorkflowName"))
        End If
        If para.ContainsKey("WorkflowType") Then
            strSql += String.Format(" and w.WORKFLOWTYPE = '{0}'", para("WorkflowType"))
        End If

        If para.ContainsKey("ProductName") Then
            strSql += String.Format(" and pb.ProductName like '%{0}%'", para("ProductName"))
        End If

        Dim paraPage As New uMESPagingDataDTO
        paraPage.CurrentPageIndex = Convert.ToInt32(para("CurrentPageIndex"))
        paraPage.PageSize = Convert.ToInt32(para("PageSize").ToString)
        paraPage.strSQL = strSql.ToString
        '主数据进行分页
        GetWorkflowinfo = DatabaseHelper.RunProcedureForPage(paraPage)
    End Function


    ''' <summary>
    ''' 根据件号获取分段件号信息 create by tianFW 2018年7月25日
    ''' </summary>
    ''' <param name="productname">件号名称</param>
    ''' <param name="productID">件号ID</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSubsectionProductInfo(ByVal productname As String, ByVal productID As String) As DataTable Implements uLMSCommonIBusiness.GetSubsectionProductInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT pb.productname ||':'||p.productrevision productname,p.productid,pb.productname pname,p.productrevision prevision,p.description pdesc")
        strsql.AppendLine("FROM product p ")
        strsql.AppendLine("LEFT JOIN producttype pt ON pt.producttypeid = p.producttypeid")
        strsql.AppendLine("LEFT JOIN productbase pb ON pb.productbaseid = p.productbaseid")
        strsql.AppendFormat("WHERE p.workflowroute='{0}' AND pt.producttypename <> '子工艺虚拟件'", productname)
        If productID <> "" Then
            strsql.AppendFormat(" OR (pb.productname = '{0}' AND P.productid <> '{1}')", productname, productID)
        End If
        strsql.AppendLine(" ORDER BY pb.productname,p.productrevision")
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function
    ''' <summary>
    ''' Add by Yuxj20180730 获取排故类型
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>    
    Function GetReworkReasonByGroupName(ByVal strGroupName As String) As DataTable Implements uLMSCommonIBusiness.GetReworkReasonByGroupName
        Dim sb = New StringBuilder
        sb.AppendLine("SELECT LR.REWORKREASONID,LR.NOTES, LR.REWORKREASONNAME, LR.DESCRIPTION,LR.REWORKREASONNAME||LR.DESCRIPTION FECOD ") 'add YangJiang LR.LOSSREASONNAME||LR.DESCRIPTION FECOD
        sb.AppendLine("FROM reworkreasongroup L")
        sb.AppendLine(" LEFT JOIN NAMEDOBJECTGROUPENTRIES N    ON N.NAMEDOBJECTGROUPID = L.REWORKREASONGROUPID")
        sb.AppendLine(" LEFT JOIN reworkreason LR ON LR.REWORKREASONID = N.ENTRIESID")
        sb.AppendLine(" LEFT JOIN Userattribute u ON L.reworkreasongroupname=u.attributevalue ")
        sb.AppendFormat("WHERE u.userattributename ='{0}' ", strGroupName)
        sb.AppendLine("  ORDER BY N.SEQUENCE ")
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetReworkReasonByGroupName = New DataTable
        Else
            GetReworkReasonByGroupName = dt
        End If
    End Function

    ''' <summary>
    ''' add YangJiang 20180802 获取企业下的角色
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEnterpriseRole() As System.Data.DataTable Implements IBusiness.uLMSCommonIBusiness.GetEnterpriseRole
        Dim strSQL As String =
            <string>                
                    SELECT r.roleid,r.rolename FROM ENTERPRISE e
                    LEFT JOIN Userattribute u ON u.parentid=e.enterpriseid
                    LEFT JOIN roledef r ON r.rolename=u.attributevalue
                    WHERE r.roleid IS NOT NULL
            </string>
        Return DatabaseHelper.Query_ReturnDatTable(strSQL)
    End Function

    ''' <summary>
    ''' 获取暂停或释放批次原因 create by tianFW 2018年8月22日
    ''' </summary>
    ''' <param name="type">1 暂停原因，0 释放原因</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetHoldOrReleaseReason(ByVal type As Integer) As DataTable Implements uLMSCommonIBusiness.GetHoldOrReleaseReason
        Dim strsql As String = ""
        If type = 1 Then
            strsql = "SELECT hr.holdreasonid reasonid,hr.holdreasonname reasonname FROM holdreason hr"
        Else
            strsql = "SELECT rr.releasereasonid reasonid,rr.releasereasonname reasonname FROM Releasereason rr"
        End If
        Return DatabaseHelper.Query_ReturnDatTable(strsql)
    End Function
    ''' <summary>
    ''' 根据批次和工序查询是否完工
    ''' </summary>
    ''' <param name="containerID"></param>
    ''' <param name="stepID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function IsContainerStepComplete(ByVal containerID As String, ByVal stepID As String, Optional ByVal beginSeq As Integer = 0) As DataTable
        Dim strSql = <string>SELECT *  FROM (
                        SELECT csw.workflowstepid,NVL2(csw.specimenqty,3,csw.checktype) checktype,c.qty,NVL(SUM(cfci.acceptanceqty),SUM(cci.acceptanceqty)) passqty 
                         FROM containerstepworkreport csw
                        left join workflowstep ws on ws.workflowstepid=csw.workflowstepid
                        LEFT JOIN containercheckinfo cci ON  cci.isuse=0 AND CCI.CONTAINERSTEPWORKREPORTID=CSW.CONTAINERSTEPWORKREPORTID                       
                        LEFT JOIN containerfinishedcheckinfo cfci ON cfci.isuse=0 AND CFCI.containerfinishedcheckinfoID=CSW.containerfinishedcheckinfoID
                        LEFT JOIN container c ON c.containerid=csw.containerid
                        WHERE csw.isuse=0
                     </string>.Value
        strSql += String.Format(" and csw.containerid='{0}' ", containerID)
        If String.IsNullOrWhiteSpace(stepID) And beginSeq = 0 Then

        Else
            If Not String.IsNullOrWhiteSpace(stepID) Then
                strSql += String.Format(" and csw.workflowstepid='{0}'", stepID)
            End If

            If beginSeq <> 0 Then
                strSql += String.Format(" and ws.sequence>={0}", beginSeq)
            End If
        End If

        strSql += " GROUP BY csw.workflowstepid,NVL2(csw.specimenqty,3,csw.checktype),c.qty ) WHERE passqty>=qty OR (nvl(passqty,0)>0 AND checktype in(3,4))"

        Return DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' create by YangSJ 2018年11月05日
    ''' 获取用户信息，返回CurrentUserInfo
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetUserInfo(ByVal strEmployeeName As String, ByVal strSessionID As String) As CurrentUserInfo Implements uLMSCommonIBusiness.GetUserInfo
        Dim UserInfo As New CurrentUserInfo
        Dim strSelect As String = <string>
                SELECT e.employeename,e.employeeid,e.fullname,f.factoryname,f.factoryid,f.description AS FactoryEName,wc.workcentername,
                wc.workcenterID,o.operationname,e.cardnum,eroles.rolenames,te.teamid,te.teamname,e.password,nvl(e.shiftid,te.shiftid) shiftid,
                r.resourcename,e.paycard,orgf.factoryname orgfactory,orgwc.workcentername orgworkcenter,orgt.teamname orgteam,e.sealimgurl,ut.attributevalue factorycode
                FROM employee e 
                                  </string>
        Dim sb As New StringBuilder
        sb.AppendLine(strSelect)
        sb.AppendLine(<string> 
        LEFT JOIN sessionvalues sv ON sv.sessionvaluesid = e.sessionvaluesid 
        LEFT JOIN factory f ON f.factoryid = sv.factoryid
        left join userattribute ut on ut.parentid=f.factoryid and ut.userattributename='分厂代码'
        LEFT JOIN workcenter wc ON wc.workcenterid = sv.workcenterid 
        LEFT JOIN operation o ON o.operationid = sv.operationid 
        LEFT JOIN resourcedef r ON r.resourceid = e.resourceid
        LEFT JOIN ( SELECT e.employeeid,wm_concat(r.rolename) AS rolenames  FROM employeerole er 
        LEFT JOIN employee e ON e.employeeid = er.employeeid  
        LEFT JOIN roledef r ON r.roleid = er.roleid  GROUP BY e.employeeid  ) eroles ON eroles.employeeid = e.employeeid 
        LEFT JOIN (SELECT  t.teamname,t.teamid,te.employeeid,t.shiftid FROM teamemployee te 
        LEFT JOIN team t  ON t.teamid = te.teamid  ) te  ON te.employeeid = e.employeeid AND ROWNUM = 1 
        LEFT JOIN factory orgf ON orgf.factoryid = e.orgfactoryid 
        LEFT JOIN workcenter orgwc ON orgwc.workcenterid = e.orgworkcenterid 
        LEFT JOIN team orgt  ON orgt.teamid = e.orgteamid
    </string>)
        sb.AppendFormat("  WHERE LOWER(e.employeename) = LOWER('{0}')", strEmployeeName)
        Dim result As New uMESProcessResult
        Try
            Dim DT As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
            Dim dr As DataRow = DT.Rows(0)
            UserInfo.EmployeeName = dr("EmployeeName").ToString
            UserInfo.FullName = dr("FullName").ToString
            UserInfo.CardNum = dr("CardNum").ToString
            UserInfo.Operation = dr("OperationName").ToString
            UserInfo.Resource = dr("ResourceName").ToString
            UserInfo.WorkCenter = dr("WorkCenterName").ToString
            UserInfo.WorkCenterID = dr("WorkCenterID").ToString
            UserInfo.Team = dr("TeamName").ToString
            UserInfo.TeamID = dr("TeamID").ToString
            UserInfo.Factory = dr("FactoryName").ToString
            UserInfo.FactoryID = dr("FactoryID").ToString
            UserInfo.FactoryEName = dr("FactoryEName").ToString
            UserInfo.PayCard = dr("PayCard").ToString
            UserInfo.Roles = dr("RoleNames").ToString
            UserInfo.EmployeeID = dr("employeeid").ToString
            UserInfo.ShiftID = dr("shiftid").ToString()
            UserInfo.Password = dr("PassWord").ToString()
            UserInfo.HomePage = dr("sealimgurl").ToString()
            UserInfo.SessionID = Guid.NewGuid.ToString
            UserInfo.SealImgUrl = dr("sealimgurl").ToString
            UserInfo.OrgInfo = String.Format("{0}  {1}  {2}", dr("orgfactory"), dr("orgworkcenter"), dr("orgteam"))
            UserInfo.FactoryCode = dr("factorycode").ToString
            sb.Clear()
            sb.AppendLine(<string>
                  SELECT MI.CAPTION, MI.WORKINGSECTIONURL, MI.URL, MI.SEQUENCE, MI.MENUITEMTYPE, SM.MENUDEFINITIONNAME SUBMENUNAME
                  FROM MENUDEFINITION M
                  LEFT JOIN MENUITEM MI ON MI.PARENTID = M.MENUDEFINITIONID
                  LEFT JOIN MENUDEFINITION SM ON SM.MENUDEFINITIONID = MI.MENUDEFINITIONID
                  LEFT JOIN EMPLOYEE E  ON E.WEBMENUDEFINITIONID = M.MENUDEFINITIONID
                  </string>)
            sb.AppendFormat(" WHERE LOWER(E.EMPLOYEENAME) = LOWER('{0}')  ORDER BY  MI.SEQUENCE ", strEmployeeName)
            Dim menuDT As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
            UserInfo.Menu = menuDT

            If Not String.IsNullOrWhiteSpace(strSessionID) Then
                Dim strQuery As String = String.Format(" DELETE FROM ACTIVEUSERSESSION WHERE ACTIVEUSERSESSIONID='{0}'", strSessionID)
                DatabaseHelper.ExecuteSql(strQuery)
            End If
        Catch ex As Exception
        End Try

        Return UserInfo
    End Function

    ''' <summary>
    ''' Add by Yuxj20181207
    ''' 施工单创建时记录组
    ''' </summary>
    ''' <param name="wfid"></param>
    ''' <param name="dr"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function UpdateTeamIdByStepAndWfId(ByVal wfid As String, ByVal dr As DataRow) As Boolean Implements uLMSCommonIBusiness.UpdateTeamIdByStepAndWfId
        UpdateTeamIdByStepAndWfId = False
        Dim strSql As String =
            String.Format("update workflowstep wfs set teamid='{0}',workcenterid='{1}' where workflowid='{2}' and workflowstepName='{3}' ",
                                          IIf(IsDBNull(dr("TeamId")), String.Empty, dr("TeamId")),
                                          IIf(IsDBNull(dr("workcenterid")), String.Empty, dr("workcenterid")),
                                          wfid, dr("StepName"))
        DatabaseHelper.ExecuteSql(strSql)
        UpdateTeamIdByStepAndWfId = True
    End Function

    ''' <summary>
    ''' 插入新的件号工艺关联关系  create by tianFW 2018年12月8日
    ''' </summary>
    ''' <param name="productID">件号ID</param>
    ''' <param name="workflowID">工艺ID</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function InsertIntoProMappingWF(ByVal productID As String, ByVal workflowID As String) As Boolean Implements uLMSCommonIBusiness.InsertIntoProMappingWF
        Dim strsql As New StringBuilder
        strsql.AppendFormat("INSERT INTO productworkflowmapping(productid,workflowid) VALUES('{0}','{1}')", productID, workflowID)
        If DatabaseHelper.ExecuteSql(strsql.ToString()) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 查询表信息根据条件
    ''' add:Wangjh 20190117
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="conditionFiled"></param>
    ''' <param name="conditionFiledValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetTableInfo(ByVal tableName As String, ByVal conditionFiled As String, ByVal conditionFiledValue As String) As DataTable Implements uLMSCommonIBusiness.GetTableInfo
        Dim strSql As String = " select *  from " + tableName + " where " + conditionFiled + "='" + conditionFiledValue + "'"
        Return DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function
    ''' <summary>
    ''' 删除表，根据条件
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="conditionPara"></param>
    ''' <param name="conditionLikePara"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function DeleteTableByField(ByVal tableName As String, ByVal conditionPara As Dictionary(Of String, String), ByVal conditionLikePara As Dictionary(Of String, String)) As Boolean Implements uLMSCommonIBusiness.DeleteTableByField
        Dim selectSql As String = "delete  from " + tableName + " where 1=1 "
        If conditionPara IsNot Nothing Then
            For Each conditionKey As String In conditionPara.Keys
                If String.IsNullOrWhiteSpace(conditionPara(conditionKey)) Or conditionPara(conditionKey) = "''" Then
                    selectSql += " and " + conditionKey + " is null "
                Else
                    selectSql += " and " + conditionKey + "=" + conditionPara(conditionKey)
                End If
            Next
        End If
        If conditionLikePara IsNot Nothing Then
            For Each conditionLikeKey As String In conditionLikePara.Keys
                If String.IsNullOrWhiteSpace(conditionLikePara(conditionLikeKey)) Or conditionLikePara(conditionLikeKey) = "''" Then
                    selectSql += " and " + conditionLikeKey + " is null "
                Else
                    selectSql += " and " + conditionLikeKey + " like '%" + conditionLikePara(conditionLikeKey) + "%'"
                End If
            Next
        End If
        If DatabaseHelper.ExecuteSql(selectSql) > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 查询表数据根据某些条件
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="conditionPara"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetTableInfoByField(ByVal tableName As String, ByVal conditionPara As Dictionary(Of String, String), ByVal conditionLikePara As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetTableInfoByField
        Dim selectSql As String = "select t.rowid,t.* from " + tableName + " t where 1=1 "
        If conditionPara IsNot Nothing Then
            For Each conditionKey As String In conditionPara.Keys
                If String.IsNullOrWhiteSpace(conditionPara(conditionKey)) Or conditionPara(conditionKey) = "''" Then
                    selectSql += " and " + conditionKey + " is null "
                Else
                    selectSql += " and " + conditionKey + "=" + conditionPara(conditionKey)
                End If
            Next
        End If
        If conditionLikePara IsNot Nothing Then
            For Each conditionLikeKey As String In conditionLikePara.Keys
                If String.IsNullOrWhiteSpace(conditionLikePara(conditionLikeKey)) Or conditionLikePara(conditionLikeKey) = "''" Then
                    selectSql += " and " + conditionLikeKey + " is null "
                Else
                    selectSql += " and " + conditionLikeKey + " like '%" + conditionLikePara(conditionLikeKey) + "%'"
                End If
            Next
        End If

        Return DatabaseHelper.Query_ReturnDatTable(selectSql)
    End Function

    ''' <summary>
    ''' 查询表数据根据某些条件,分页查询
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="conditionPara"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetPageTableInfoByField(ByVal tableName As String, ByVal conditionPara As Dictionary(Of String, String), ByVal conditionLikePara As Dictionary(Of String, String), ByVal currentPage As Integer, ByVal pageSize As Integer) As uMESProcessResult Implements uLMSCommonIBusiness.GetPageTableInfoByField
        Dim selectSql As String = "select t.* from " + tableName + " t where 1=1 "
        If conditionPara IsNot Nothing Then
            For Each conditionKey As String In conditionPara.Keys
                If String.IsNullOrWhiteSpace(conditionPara(conditionKey)) Or conditionPara(conditionKey) = "''" Then
                    selectSql += " and " + conditionKey + " is null "
                Else
                    selectSql += " and " + conditionKey + "=" + conditionPara(conditionKey)
                End If
            Next
        End If
        If conditionLikePara IsNot Nothing Then
            For Each conditionLikeKey As String In conditionLikePara.Keys
                If String.IsNullOrWhiteSpace(conditionLikePara(conditionLikeKey)) Or conditionLikePara(conditionLikeKey) = "''" Then
                    selectSql += " and " + conditionLikeKey + " is null "
                Else
                    selectSql += " and " + conditionLikeKey + " like '%" + conditionLikePara(conditionLikeKey) + "%'"
                End If
            Next
        End If

        Dim paraPage As New uMESPagingDataDTO
        paraPage.CurrentPageIndex = currentPage
        paraPage.PageSize = pageSize
        paraPage.strSQL = selectSql.ToString
        Dim result As uMESProcessResult = DatabaseHelper.RunProcedureForPage(paraPage)
        Return result
    End Function


    ''' <summary>
    ''' 更新表的某些字段，根据条件
    ''' add:Wangjh 2018/1/28
    ''' 后续弃用
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="updatePara"></param>
    ''' <param name="conditionPara"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function updateTableInfo(ByVal tableName As String, ByVal updatePara As Dictionary(Of String, String), ByVal conditionPara As Dictionary(Of String, String)) As Boolean Implements uLMSCommonIBusiness.updateTableInfo
        updateTableInfo = False
        If updatePara.Count = 0 And conditionPara.Count = 0 Then
            Exit Function
        End If
        Dim strSql As String = String.Concat("UPDATE ", tableName, " SET ")
        Dim n = 0
        For Each updateKey As String In updatePara.Keys
            If n = 0 Then
                strSql += updateKey + "=" + updatePara(updateKey) + ""
            Else
                strSql += "," + updateKey + "=" + updatePara(updateKey) + ""
            End If
            n += 1
        Next
        n = 0
        For Each conditionKey As String In conditionPara.Keys
            If n = 0 Then
                strSql += " where " + conditionKey + "=" + conditionPara(conditionKey) + ""
            Else
                strSql += " and " + conditionKey + "=" + conditionPara(conditionKey) + ""
            End If
            n += 1
        Next
        If Not DatabaseHelper.ExecuteSql(strSql) > 0 Then
            Exit Function
        End If
        updateTableInfo = True
    End Function

    ''' <summary>
    ''' 更新某些信息根据某些条件
    ''' 后续弃用
    ''' </summary>
    ''' <param name="updatePara"></param>
    ''' <param name="conditionPara"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function UpdateTableByField(ByVal tableName As String, ByVal updatePara As Dictionary(Of String, Object), ByVal conditionPara As Dictionary(Of String, String)) As Boolean Implements uLMSCommonIBusiness.UpdateTableByField
        UpdateTableByField = False
        If updatePara.Count = 0 Then
            Exit Function
        End If
        If conditionPara.Count = 0 Then
            Exit Function
        End If

        Dim strSql As String = "UPDATE " + tableName + " SET "
        Dim n = 0
        For Each updateKey As String In updatePara.Keys
            If n = 0 Then
                If updatePara(updateKey).GetType.ToString() = "System.DateTime" Then
                    strSql += updateKey + "=to_date('" + Date.Parse(updatePara(updateKey)).ToString("yyyy/MM/dd") + "','yyyy/MM/dd')" 'HH:mm:ss
                Else
                    If String.IsNullOrWhiteSpace(updatePara(updateKey)) Then
                        strSql += updateKey + "=" + "''"
                    Else
                        strSql += updateKey + "=" + updatePara(updateKey) + ""
                    End If
                End If
            Else
                If updatePara(updateKey).GetType.ToString() = "System.DateTime" Then
                    strSql += "," + updateKey + "=to_date('" + Date.Parse(updatePara(updateKey)).ToString("yyyy/MM/dd") + "','yyyy/MM/dd')" 'HH:mm:ss
                Else
                    If String.IsNullOrWhiteSpace(updatePara(updateKey)) Then
                        strSql += "," + updateKey + "=" + "''"
                    Else
                        strSql += "," + updateKey + "=" + updatePara(updateKey)
                    End If
                End If
            End If
            n += 1
        Next
        n = 0
        For Each conditionKey As String In conditionPara.Keys
            Dim rowCondition As String = ""
            If String.IsNullOrWhiteSpace(conditionPara(conditionKey)) Or conditionPara(conditionKey) = "''" Then
                rowCondition = conditionKey + " is null "
            Else
                rowCondition = conditionKey + "=" + conditionPara(conditionKey)
            End If
            If n = 0 Then
                strSql += " where " + rowCondition
            Else
                strSql += " and " + rowCondition
            End If
            n += 1
        Next
        If Not DatabaseHelper.ExecuteSql(strSql) > 0 Then
            Exit Function
        End If
        UpdateTableByField = True
    End Function


    ''' <summary>
    ''' 插入表
    ''' </summary>
    ''' <param name="tableName"></param>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function InsertTableInfo(ByVal tableName As String, ByVal para As Dictionary(Of String, Object)) As Boolean Implements uLMSCommonIBusiness.InsertTableInfo
        InsertTableInfo = False
        If para.Count = 0 Then
            Exit Function
        End If
        Dim strSql As String = FillInsertTableInfo(tableName, para)
        If DatabaseHelper.ExecuteSql(strSql) > 0 Then
            InsertTableInfo = True
        End If
    End Function

    Function FillInsertTableInfo(ByVal tableName As String, ByVal para As Dictionary(Of String, Object)) As String Implements uLMSCommonIBusiness.FillInsertTableInfo
        Dim strSql As String = "insert into " + tableName + " ( "
        Dim n = 0
        For Each key As String In para.Keys
            strSql += key + ","

            If n = para.Keys.Count - 1 Then
                strSql = strSql.Substring(0, strSql.Length - 1) + ")"
            End If
            n += 1
        Next
        n = 0
        For Each key As String In para.Keys
            If n = 0 Then
                strSql += " values ("
            End If
            If para(key).GetType.ToString() = "System.DateTime" Then
                strSql += "to_date('" + Date.Parse(para(key)).ToString("yyyy/MM/dd") + "','yyyy/MM/dd'),"
            Else
                If String.IsNullOrWhiteSpace(para(key)) Then
                    strSql += "'',"
                Else
                    strSql += para(key) + ","
                End If
            End If

            If n = para.Count - 1 Then
                strSql = strSql.Substring(0, strSql.Length - 1) + ")"
            End If
            n += 1
        Next
        Return strSql
    End Function

    ''' <summary>
    ''' 获取工区对应员工 Add by Yuxj20190123
    ''' </summary>
    ''' <param name="WorkCenterID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetWorkCenterEmployeeInfo(ByVal WorkCenterID As String) As DataTable Implements uLMSCommonIBusiness.GetWorkCenterEmployeeInfo
        Dim strsql As New StringBuilder
        strsql.AppendLine("SELECT e.*,t.TEAMID,t.TEAMNAME FROM EMPLOYEE E")
        strsql.AppendLine("LEFT JOIN  SESSIONVALUES SV ON SV.SESSIONVALUESID = E.SESSIONVALUESID")
        strsql.AppendLine("LEFT JOIN teamemployee tem ON tem.employeeid = e.employeeid")
        strsql.AppendLine("LEFT JOIN team t ON t.teamid = tem.teamid ")
        strsql.AppendLine("LEFT JOIN WORKCENTER WC ON WC.WORKCENTERID = SV.WORKCENTERID")
        strsql.AppendFormat(" WHERE WC.WORKCENTERID = '{0}' ", WorkCenterID)
        Return DatabaseHelper.Query_ReturnDatTable(strsql.ToString())
    End Function

    ''' <summary>
    ''' 获取工装工具信息
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetToolData(ByVal para As Dictionary(Of String, String)) As uMESProcessResult Implements uLMSCommonIBusiness.GetToolData


        Dim condition As String = " where 1=1 "
        If para.ContainsKey("Description") Then
            condition += String.Format(" and t.description like '%{0}%' ", para("Description"))
        End If

        If para.ContainsKey("Drawingno") Then
            condition += String.Format(" and t.drawingno like '%{0}%' ", para("Drawingno"))
        End If

        Dim strSql As String = <string> select t.cuttoolname toolno,t.description,t.drawingno,'刀具' ToolType,t.cuttoolid toolid from cuttool t </string>.Value
        strSql += condition
        If para.ContainsKey("ToolNo") Then
            strSql += String.Format(" and t.cuttoolname like '%{0}%'", para("ToolNo"))
        End If
        strSql += " UNION ALL "

        strSql += <string> select t.measuretoolname toolno,t.description,t.drawingno,'量具' ToolType,t.measuretoolid toolid from measuretool t </string>.Value
        strSql += condition
        If para.ContainsKey("ToolNo") Then
            strSql += String.Format(" and t.measuretoolname like '%{0}%'", para("ToolNo"))
        End If
        strSql += " UNION ALL "

        strSql += <string> select t.specialtoolname toolno,t.description,t.drawingno,'夹模具' ToolType,t.specialtoolid toolid from specialtool t </string>.Value
        strSql += condition
        If para.ContainsKey("ToolNo") Then
            strSql += String.Format(" and t.specialtoolname like '%{0}%'", para("ToolNo"))
        End If

        strSql = " select * from ( " + strSql + " )"

        Dim paraPage As New uMESPagingDataDTO
        paraPage.CurrentPageIndex = Convert.ToInt32(para("CurrentPageIndex"))
        paraPage.PageSize = Convert.ToInt32(para("PageSize").ToString)
        paraPage.strSQL = strSql

        Return DatabaseHelper.RunProcedureForPage(paraPage)

    End Function

    ''' <summary>
    ''' Add by Yuxj20200418
    ''' 获取管理者标准作业页面人员列表
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetSealimgurlEmployeeData(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetSealimgurlEmployeeData
        Dim strsql As String =
            <string>
                SELECT e.fullname,e.employeename,wc.workcentername,wc.workcenterid,f.factoryname,
                        f.factoryid,e.employeeid,t.teamname ,s.shiftname
                FROM employee e
                LEFT JOIN Sessionvalues sv ON e.employeeid=sv.employeeid
                LEFT JOIN Workcenter wc ON wc.workcenterid=sv.workcenterid
                LEFT JOIN Factory f ON f.factoryid=sv.factoryid 
                LEFT JOIN shift s ON s.shiftid=e.shiftid
                LEFT JOIN teamemployee te ON te.employeeid=e.employeeid
                LEFT JOIN team t ON t.teamid=te.teamid                                  
            </string>

        If para.ContainsKey("roleid") Then
            strsql += "  LEFT JOIN employeerole er ON er.employeeid=e.employeeid "
            strsql += "  LEFT JOIN Roledef rd ON rd.roleid=er.roleid "
        End If

        strsql += "  WHERE e.notes LIKE '%职务:%' "

        If para.ContainsKey("roleid") Then
            strsql += String.Format(" and rd.roleid='{0}'", para("roleid"))
        End If
        If para.ContainsKey("factoryid") Then
            strsql += String.Format(" and f.factoryid='{0}'", para("factoryid"))
        End If

        If para.ContainsKey("workcenterid") Then
            strsql += String.Format(" and wc.workcenterid='{0}'", para("workcenterid"))
        End If

        If para.ContainsKey("fullname") Then
            strsql += String.Format(" and e.fullname like '%{0}%'", para("fullname"))
        End If

        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql)
        Return dt
    End Function

    ''' <summary>
    ''' Modify by Yuxj20200603增加施工单信息查询
    ''' </summary>
    ''' <param name="wfid"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetTempWorkFlowData(ByVal wfid As String) As DataTable Implements uLMSCommonIBusiness.GetTempWorkFlowData
        Dim strsql As String =
            <string>
                SELECT wfb.workflowname,wf.ly2modle_node,wfs.workflowstepname,si.Description StepinfoDesc,
                        sib.stepinfoname ,WC.WORKCENTERID,WC.WORKCENTERNAME,T.TEAMID,T.TEAMNAME
                FROM workflow wf
                LEFT JOIN workflowbase wfb ON wfb.workflowbaseid=wf.workflowbaseid
                LEFT JOIN workflowstep wfs ON wfs.workflowid=wf.workflowid
                LEFT JOIN stepinfo SI ON si.Workflowstepid=wfs.workflowstepid
                LEFT JOIN stepinfobase sib ON si.Stepinfobaseid=sib.stepinfobaseid
                LEFT JOIN WORKCENTER WC ON WC.WORKCENTERID=WFS.WORKCENTERID
                LEFT JOIN TEAM T ON T.TEAMID=WFS.TEAMID
            </string>
        strsql += String.Format(" where wf.workflowid='{0}'", wfid)
        strsql += " ORDER BY wfs.sequence ASC "
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql)
        Return dt
    End Function

    Function GetRecombineTempWorkFlowData(ByVal para As Dictionary(Of String, String)) As DataSet Implements uLMSCommonIBusiness.GetRecombineTempWorkFlowData
        Dim ds As New DataSet
        Dim strsql As String =
            <string>
                SELECT wfb.workflowname,wf.workflowrevision,wf.description,wf.createdatetime,
                getonlyfullname(wf.createemployeeid) createfullname ,getonlyfullname(wf.checkemployeeid) checkfullname,
                getonlyfullname(wf.zgemployeeid) zgfullname,wf.phasenode,wf.ly2modle_node,wf.process_no 
                FROM workflow wf 
                LEFT JOIN workflowbase wfb ON wf.workflowbaseid=wfb.workflowbaseid
                WHERE wf.workflowid='{0}'
            </string>
        strsql = String.Format(strsql, para("WorkflowID"))
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strsql)
        dt.TableName = "WorkFlowName"
        ds.Tables.Add(dt)
        strsql = <string>
                    SELECT wfs.workflowid,wfs.workflowstepname,wfs.workflowstepid,sp.specname,
                           s.specno,s.specrevision,wfs.teamid,wfs.workcenterid,
                           DECODE(wfs.wipmsglabel,'子工艺','SubWorkflow','Spec') WFSTYPE
                    FROM workflowstep wfs
                    LEFT JOIN specbase sp1 ON sp1.specbaseid=wfs.specbaseid
                    LEFT JOIN spec s ON s.specid=NVL(sp1.revofrcdid,wfs.specid)
                    LEFT JOIN specbase sp ON sp.specbaseid=s.specbaseid
                    WHERE wfs.workflowid='{0}'
                    ORDER BY wfs.sequence ASC
                 </string>
        strsql = String.Format(strsql, para("WorkflowID"))
        dt = DatabaseHelper.Query_ReturnDatTable(strsql)
        dt.TableName = "WorkFlowStep"
        ds.Tables.Add(dt)
        Return ds
    End Function

    '''create by Yangsj 20200825
    '''获取子工艺批次初始数量，取主工艺对应工序上一序的检验合格数
    Public Function GetSonContainerStarQty(ByVal facontainername As String, ByVal sonworkflowid As String) As String Implements uLMSCommonIBusiness.GetSonContainerStarQty
        Dim strSql As String = String.Format(<string> SELECT SUM(CR.PASSQTY)
                      FROM CONTAINERSTEPRECORD CR
                      LEFT JOIN PATH P    ON P.FROMSTEPID = CR.WORKFLOWSTEPID
                      LEFT JOIN (SELECT DISTINCT SSS.WORKFLOWID,SSS.WORKFLOWSTEPID,SSS.SONWORKFLOWID FROM  STEPSUBSTEP SSS)SU   
                      ON SU.WORKFLOWSTEPID = P.TOSTEPID AND SU.WORKFLOWID = CR.WORKFLOWID
                     WHERE CR.USECOMPLETED = 1 AND CR.CONTAINERNAME = '{0}'   AND SU.SONWORKFLOWID = '{1}'
                     GROUP BY CR.CONTAINERNAME, CR.WORKFLOWSTEPNAME</string>.Value, facontainername, sonworkflowid)

        Dim obj As Object = DatabaseHelper.GetSingle(strSql)
        If IsDBNull(obj) OrElse IsNothing(obj) Then
            Return String.Empty
        Else
            Return obj.ToString
        End If
    End Function

    ''' <summary>
    ''' 获取子工艺信息，包含通用子工艺
    ''' add:Wangjh 20220114
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSubWorkflowInfo(ByVal para As Dictionary(Of String, String)) As DataTable Implements uLMSCommonIBusiness.GetSubWorkflowInfo
        Dim strSql = <string> select t.* from(
SELECT sbs.workflowid,sbs.workflowstepid,subw.productid subproductid,sbs.sonworkflowid subworkflowid,swb.workflowname subworkflowname,subw.workflowrevision subworkflowrevision FROM stepsubstep sbs
inner join workflow subw on subw.workflowid=sbs.sonworkflowid
left join workflowbase swb on swb.workflowbaseid=subw.workflowbaseid         
left join workflowstep sws on sws.workflowstepid=sbs.sonworkflowstepid--子工艺的工序  
left join specbase sb on sb.specbaseid=sws.specbaseid
left join spec s on s.specid=nvl(sb.revofrcdid,sws.specid)----子工艺的工序
where NVL2(s.commonsubworkflow,'1','0')='0'  
union all
--三层通用子工艺情况下，subproductid非通用工艺的件号，而是第二层虚拟子工艺的件号，这样创出的子卡到时批次调度无法换通用工艺的版本
SELECT sbs.workflowid,sbs.workflowstepid,w.productid subproductid,subw.workflowid subworkflowid,swb.workflowname subworkflowname,subw.workflowrevision subworkflowrevision FROM
(SELECT w.workflowid,w.productid  FROM workflow w
LEFT JOIN workflowstep ws ON ws.workflowid=w.workflowid
WHERE w.factoryid='{0}'
GROUP BY w.workflowid,w.productid
having count(ws.workflowstepid)=1) w--通用工艺情况下，第二层虚拟子工艺 
LEFT JOIN workflowstep ws ON ws.workflowid=w.workflowid
left join specbase sb on sb.specbaseid=ws.specbaseid
left join spec s on s.specid=nvl(sb.revofrcdid,ws.specid)        
INNER join workflow subw on subw.process_no=s.commonsubworkflow--通用孙子工艺
inner join workflowbase swb on swb.revofrcdid=subw.workflowid
LEFT JOIN stepsubstep sbs ON sbs.sonworkflowid=w.workflowid--第二层虚拟子工艺的关联信息
INNER JOIN workflow fw ON fw.workflowid=sbs.workflowid--第一层工艺，主工艺
WHERE   NVL2(s.commonsubworkflow,'1','0')='1' --AND sbs.workflowstepid='00074e80001aa1ab'
GROUP BY sbs.workflowid,sbs.workflowstepid,subw.workflowid,w.productid,swb.workflowname,subw.workflowrevision
 ) t where 1=1 </string>.Value

        strSql = String.Format(strSql, para("FactoryID")) '子工艺车间信息

        Dim condition = ""
        If para.ContainsKey("WorkflowStepID") Then '父工序
            If Not String.IsNullOrWhiteSpace(para("WorkflowStepID")) Then
                condition += String.Format(" and t.workflowstepid='{0}' ", para("WorkflowStepID"))
            End If
        End If


        If para.ContainsKey("WorkflowID") Then '父工艺
            If Not String.IsNullOrWhiteSpace(para("WorkflowID")) Then
                condition += String.Format(" and t.WorkflowID='{0}' ", para("WorkflowID"))
            End If
        End If

        strSql += condition

        Return DatabaseHelper.Query_ReturnDatTable(strSql)

    End Function

    ''' <summary>
    ''' 判断批次是否暂停，给出暂停原因
    ''' add:Wangjh 20220414
    ''' </summary>
    ''' <param name="containerId"></param>
    ''' <param name="strMsg"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function JudeContainerHold(ByVal containerId As String, ByRef strMsg As String) As Boolean Implements uLMSCommonIBusiness.JudeContainerHold

        Dim strSql = "select 1 from containercurrentinfo cci where cci.containerid='{0}' and cci.ishold=1 "
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(String.Format(strSql, containerId))

        If dt.Rows.Count = 0 Then
            Return False
        End If

        strSql = "select operreason from opercontainerrecord op where op.containerid='{0}' and op.opertype=2 order by op.createdate desc"
        Dim holdDt As DataTable = DatabaseHelper.Query_ReturnDatTable(String.Format(strSql, containerId))

        If holdDt.Rows.Count = 0 Then
            Return False
        Else
            strMsg = holdDt.Rows(0)("operreason").ToString()
            Return True
        End If

    End Function

    ''' <summary>
    ''' 继承旧工艺属性和工艺的检测项
    ''' </summary>
    ''' <param name="oldWorkflowId"></param>
    ''' <param name="newWorkflowId"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SaveWorkflowRecombineAttrData(ByVal oldWorkflowId As String, ByVal newWorkflowId As String) As Boolean Implements uLMSCommonIBusiness.SaveWorkflowRecombineAttrData
        Try
            Dim strSql As String = <string>
SELECT ws.workflowstepid,ws.workflowstepname FROM Workflowstep ws
LEFT JOIN Workflow w ON w.workflowid = ws.workflowid
WHERE w.workflowid = '{0}'  </string>.Value
            Dim sqlList As New ArrayList
            Dim exSql As String = ""
            Dim strOld As String = String.Format(strSql, oldWorkflowId)
            Dim strNew As String = String.Format(strSql, newWorkflowId)
            Dim dtOld As DataTable = DatabaseHelper.Query_ReturnDatTable(strOld)
            Dim dtNew As DataTable = DatabaseHelper.Query_ReturnDatTable(strNew)
            For Each dr As DataRow In dtNew.Rows
                Dim rows() As DataRow = dtOld.Select(String.Format("workflowstepname='{0}'", dr("workflowstepname").ToString))
                '存在相同的工序，则复制旧工艺检测项
                If rows.Length > 0 Then
                    Dim strPoint = String.Format("SELECT s.* FROM stepcheckpoint s where s.workflowstepid = '{0}'", rows(0)("workflowstepid").ToString)
                    Dim dtPoint As DataTable = DatabaseHelper.Query_ReturnDatTable(strPoint)
                    For Each drp As DataRow In dtPoint.Rows
                        Dim stepcheckpointid As String = Guid.NewGuid().ToString
                        exSql = "INSERT INTO stepcheckpoint (STEPCHECKPOINTID,WORKFLOWSTEPID,INTIME,"
                        Dim valSql = ") VALUES('" + stepcheckpointid + "','" + dr("workflowstepid").ToString + "',sysdate,"
                        For Each col As DataColumn In dtPoint.Columns
                            If col.ColumnName.ToUpper = "STEPCHECKPOINTID" Or col.ColumnName.ToUpper = "WORKFLOWSTEPID" Or col.ColumnName.ToUpper = "INTIME" Or col.ColumnName.ToUpper = "CHECKPOINTNOTEDIS_B" Or col.ColumnName.ToUpper = "DRAWINGREQUIREDIS_B" Then
                                Continue For
                            End If
                            exSql += col.ColumnName + ","

                            If drp(col.ColumnName).ToString.Contains("'") Then '内容有单引号会导致报错，add by zhangrj 20240123
                                drp(col.ColumnName) = drp(col.ColumnName).ToString.Replace("'", "''")
                            End If

                            valSql += "'" + drp(col.ColumnName).ToString + "',"
                        Next
                        exSql = exSql.Trim(",") + valSql.Trim(",") + ")"
                        sqlList.Add(exSql)
                        'checkpointnotedis_b drawingrequiredis_b  CLOB字段超长插入失败处理
                        sqlList.Add(String.Format(<string>update stepcheckpoint set checkpointnotedis_b=(select checkpointnotedis_b from stepcheckpoint where stepcheckpointid='{0}'),
                                            drawingrequiredis_b=(select drawingrequiredis_b from stepcheckpoint where stepcheckpointid='{0}')
                                            where stepcheckpointid='{1}'</string>.Value, drp("stepcheckpointid"), stepcheckpointid))
                    Next
                End If
            Next
            '复制工艺
            exSql = ""
            strSql = "SELECT * FROM Workflow w WHERE w.workflowid = '{0}'"
            strOld = String.Format(strSql, oldWorkflowId)
            Dim dtOldWF As DataTable = DatabaseHelper.Query_ReturnDatTable(strOld)
            If dtOldWF.Rows.Count > 0 Then
                exSql = "UPDATE Workflow w SET w.part_revid = '{0}', w.ly2sequence = '{1}' WHERE w.workflowid = '{2}'"
                exSql = String.Format(exSql, dtOldWF.Rows(0)("part_revid").ToString, dtOldWF.Rows(0)("ly2sequence").ToString, newWorkflowId)
                sqlList.Add(exSql)
            End If
            '复制工艺上的附件 add:Wangjh 20230214
            strSql = "select * from objectdocinfo od where od.parentid='{0}'"
            Dim fileDt = DatabaseHelper.Query_ReturnDatTable(String.Format(strSql, oldWorkflowId))
            For Each fileRow As DataRow In fileDt.Rows
                sqlList.Add(String.Format("delete objectdocinfo od where od.parentid='{0}' and od.filename='{1}'", newWorkflowId, fileRow("filename").ToString))
                sqlList.Add(String.Format(<string>insert into objectdocinfo od (od.parentid,od.objectdocinfoid,od.filename,od.filepath)
values('{0}',sys_guid(),'{1}','{2}')</string>.Value, newWorkflowId, fileRow("filename").ToString, fileRow("filepath").ToString))
            Next

            DatabaseHelper.ExecuteSqlTran(sqlList)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    ''' <summary>
    ''' 插入附件 add by zhangrj 2022-10-21
    ''' </summary>
    ''' <param name="para"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SaveObjectFileInfo(ByVal para As Dictionary(Of String, String)) As Boolean Implements uLMSCommonIBusiness.SaveObjectFileInfo
        Try
            Dim strSql = "SELECT * FROM objectdocinfo o WHERE o.parentid = '" + para("parentId").ToString + "'"
            Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(strSql)
            strSql = ""
            If dt.Rows.Count > 0 Then
                strSql = "UPDATE objectdocinfo o SET o.filename = '{0}', o.filepath='{1}' where o.OBJECTDOCINFOID = '{2}'"
                strSql = String.Format(strSql, para("fileName").ToString, para("filePath").ToString, dt.Rows(0)("OBJECTDOCINFOID").ToString)
            Else
                strSql = "INSERT INTO objectdocinfo(OBJECTDOCINFOID,parentid,filename,filepath) VALUES("
                strSql += "'" + Guid.NewGuid.ToString + "',"
                strSql += "'" + para("parentId").ToString + "',"
                strSql += "'" + para("fileName").ToString + "',"
                strSql += "'" + para("filePath").ToString + "')"
            End If
            DatabaseHelper.ExecuteSql(strSql)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    ''' <summary>
    ''' 获取工步信息（通过工艺ID） add by zhangrj 20230628
    ''' </summary>
    ''' <param name="workflowID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetStepinfoByWorkflowID(ByVal workflowID As String) As DataTable Implements uLMSCommonIBusiness.GetStepinfoByWorkflowID
        Dim strSql = String.Format(<string>
                        SELECT ws.workflowstepname,s.stepno,s.description FROM workflowstep ws
                        LEFT JOIN stepinfo s ON s.workflowstepid= ws.workflowstepid
                        LEFT JOIN stepinfobase sb ON sb.stepinfobaseid = s.stepinfobaseid
                        WHERE ws.workflowid = '{0}'
                        ORDER BY ws.workflowstepid,s.stepseq
                     </string>.Value, workflowID)
        Return DatabaseHelper.Query_ReturnDatTable(strSql)
    End Function

    ''' <summary>
    ''' 插入功能操作日志表 add by zhangrj 20231201
    ''' </summary>
    ''' <param name="parentID"></param>
    ''' <param name="employeeID"></param>
    ''' <param name="notes"></param>
    ''' <remarks></remarks>
    Public Sub InsertCommonMethodOperaLogInfo(ByVal parentID As String, ByVal employeeID As String, ByVal notes As String, ByVal type As String) Implements uLMSCommonIBusiness.InsertCommonMethodOperaLogInfo
        Dim strSql = <string> INSERT INTO CommonMethodOperaLog(Operalogid,Parentid,Operationdate,Operationemployeeid,Notes,OPERATYPE)
                              VALUES('{0}','{1}',to_date('{2}','yyyy-mm-dd hh24:mi:ss'),'{3}','{4}','{5}') </string>.Value
        strSql = String.Format(strSql, Guid.NewGuid.ToString(), parentID, DateTime.Now.ToString(), employeeID, notes, type)
        DatabaseHelper.ExecuteSql(strSql)
    End Sub

    ''' <summary>
    ''' 获取插入功能操作日志表sql add by zhangrj 20240105
    ''' </summary>
    ''' <param name="parentID"></param>
    ''' <param name="employeeID"></param>
    ''' <param name="notes"></param>
    ''' <remarks></remarks>
    Public Function GetInsertCommonMethodOperaLogSql(ByVal parentID As String, ByVal employeeID As String, ByVal notes As String, ByVal type As String) As String Implements uLMSCommonIBusiness.GetInsertCommonMethodOperaLogSql
        Dim strSql = <string> INSERT INTO CommonMethodOperaLog(Operalogid,Parentid,Operationdate,Operationemployeeid,Notes,OPERATYPE)
                              VALUES('{0}','{1}',to_date('{2}','yyyy-mm-dd hh24:mi:ss'),'{3}','{4}','{5}') </string>.Value
        strSql = String.Format(strSql, Guid.NewGuid.ToString(), parentID, DateTime.Now.ToString(), employeeID, notes, type)
        Return strSql
    End Function

    ''' <summary>
    ''' 获取操作日志 add by zhangrj 20231206
    ''' </summary>
    ''' <param name="parentID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetCommonMethodOperaLogData(ByVal parentID As String, ByVal type As String) As DataTable Implements uLMSCommonIBusiness.GetCommonMethodOperaLogData
        Dim strSql As New StringBuilder
        strSql.AppendLine(<stirng>
                         SELECT e.fullname,cl.operationdate,cl.notes FROM CommonMethodOperaLog cl
                         LEFT JOIN employee e ON e.employeeid = cl.operationemployeeid
                         WHERE 1=1 
                     </stirng>.Value)

        If Not String.IsNullOrWhiteSpace(parentID) Then
            strSql.AppendFormat(" AND cl.parentid = '{0}'", parentID)
        End If
        If Not String.IsNullOrWhiteSpace(type) Then
            strSql.AppendFormat(" AND cl.OPERATYPE = '{0}'", type)
        End If
        strSql.AppendLine(" ORDER BY cl.operationdate DESC")
        Return DatabaseHelper.Query_ReturnDatTable(strSql.ToString())
    End Function


    ''' <summary>
    ''' 根据工艺ID获取工序的工序及子工序号
    ''' Create：duht
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowAndSonSPec(ByVal strWorkflowID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowAndSonSPec
        Dim sb As New StringBuilder
        sb.AppendLine(" SELECT  s.specid,s.specno, sb.specname,s1.specno AS sonspecno,pb.productname,p.description,wfs.MakeCycle, w.workflowid,w.workflowbaseid  FROM WORKFLOWSTEP wfs ")
        sb.AppendLine(" LEFT JOIN Workflow w ON w.workflowid=wfs.workflowid ")
        sb.AppendLine("LEFT JOIN specbase sb ON wfs.specbaseid=sb.specbaseid ")
        sb.AppendLine(" LEFT JOIN spec s ON s.specid = nvl(sb.revofrcdid,wfs.specid) ")
        sb.AppendLine(" LEFT JOIN stepsubstep sp ON sp.workflowstepid =wfs.workflowstepid  ")
        sb.AppendLine(" LEFT JOIN Workflowstep wfs1 ON wfs1.workflowstepid=sp.sonworkflowstepid  ")
        sb.AppendLine(" LEFT JOIN specbase sb1 ON sb1.specbaseid=wfs1.specbaseid  ")
        sb.AppendLine(" LEFT JOIN spec s1 ON s1.specid = nvl(sb1.revofrcdid,wfs1.specid) ")
        sb.AppendLine("LEFT JOIN product p ON p.productid=w.productid ")
        sb.AppendLine("LEFT JOIN productbase pb ON pb.productbaseid=p.productbaseid ")
        sb.AppendFormat(" WHERE w.workflowid = '{0}'   ", strWorkflowID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetWorkFlowAndSonSPec = New DataTable
        Else
            GetWorkFlowAndSonSPec = dt
        End If
    End Function

    ''' <summary>
    ''' 根据同名工艺获取其他工艺版本的工序和子工序号
    ''' Create：duht
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorkFlowOtherVersionAndSonSPec(ByVal strWorkflowID As String) As DataTable Implements IBusiness.uLMSCommonIBusiness.GetWorkFlowOtherVersionAndSonSPec
        Dim sb As New StringBuilder
        sb.AppendLine(" SELECT  s.specid,s.specno, sb.specname,s1.specno AS sonspecno,pb.productname,wfs.MakeCycle, p.description,w.workflowid,w.workflowbaseid  FROM WORKFLOWSTEP wfs ")
        sb.AppendLine(" LEFT JOIN Workflow w ON w.workflowid=wfs.workflowid ")
        sb.AppendLine("LEFT JOIN specbase sb ON wfs.specbaseid=sb.specbaseid ")
        sb.AppendLine(" LEFT JOIN spec s ON s.specid = nvl(sb.revofrcdid,wfs.specid) ")
        sb.AppendLine(" LEFT JOIN stepsubstep sp ON sp.workflowstepid =wfs.workflowstepid  ")
        sb.AppendLine(" LEFT JOIN Workflowstep wfs1 ON wfs1.workflowstepid=sp.sonworkflowstepid  ")
        sb.AppendLine(" LEFT JOIN specbase sb1 ON sb1.specbaseid=wfs1.specbaseid  ")
        sb.AppendLine(" LEFT JOIN spec s1 ON s1.specid = nvl(sb1.revofrcdid,wfs1.specid) ")
        sb.AppendLine("LEFT JOIN product p ON p.productid=w.productid ")
        sb.AppendLine("LEFT JOIN productbase pb ON pb.productbaseid=p.productbaseid ")
        sb.AppendFormat(" WHERE  EXISTS( SELECT 1 FROM Workflow ww WHERE ww.workflowid= '{0}' AND ww.workflowbaseid=w.workflowbaseid)  ", strWorkflowID)
        Dim dt As DataTable = DatabaseHelper.Query_ReturnDatTable(sb.ToString)
        If dt Is Nothing Then
            GetWorkFlowOtherVersionAndSonSPec = New DataTable
        Else
            GetWorkFlowOtherVersionAndSonSPec = dt
        End If
    End Function

    ''' <summary>
    ''' 插入推送数据中心数据变更表 add by zhangrj 20240905
    ''' </summary>
    ''' <param name="dtData"></param>
    ''' <param name="tableName"></param>
    ''' <param name="uniqueColName"></param>
    ''' <param name="toAppId"></param>
    ''' <param name="opType">1：新增，2：更新，3：删除</param>
    ''' <param name="isExcute">是否直接执行sql</param>
    ''' <remarks></remarks>
    Public Function InsertSyncTableChangeRecode(ByVal dtData As DataTable, ByVal tableName As String, ByVal uniqueColName As String, ByVal toAppId As String, ByVal opType As Integer, Optional ByVal isExcute As Boolean = True) As ArrayList Implements uLMSCommonIBusiness.InsertSyncTableChangeRecode
        tableName = tableName.ToUpper()
        uniqueColName = uniqueColName.ToUpper()
        Dim insertSql As String = "INSERT INTO sync_tablechangerecord (id,tablename,uniquecolname,uniquecolvalue,operatetype)values('{0}','{1}','{2}','{3}',{4})"
        Dim insertSql2 As String = "INSERT INTO sync_sendtoappid (parentid,toappid)values('{0}','{1}')"
        Dim tableInsertSql As String = "INSERT INTO sync_tableinfo(tablename,uniquecolname) VALUES('{0}','{1}')"
        Dim arrList As ArrayList = New ArrayList()
        If DatabaseHelper.GetSingle(String.Format("SELECT 1 FROM sync_tableinfo st WHERE st.tablename = '{0}'", tableName)) Is Nothing Then
            arrList.Add(String.Format(tableInsertSql, tableName, uniqueColName))
        End If

        If opType = 1 Then '如果是新增，则需要判断是否已经有重复值
            For Each row As DataRow In dtData.Rows
                Try
                    If String.IsNullOrWhiteSpace(row(uniqueColName).ToString()) Then
                        Continue For
                    End If
                    Dim uniqueID = Guid.NewGuid().ToString()
                    Dim dtChangeRecord = DatabaseHelper.Query_ReturnDatTable(String.Format("SELECT ID FROM sync_tablechangerecord WHERE uniquecolvalue = '{0}' AND tablename='{1}' AND operatetype = {2}", row(uniqueColName), tableName, opType))
                    If dtChangeRecord.Rows.Count = 0 Then
                        arrList.Add(String.Format(insertSql, uniqueID, tableName, uniqueColName, row(uniqueColName), opType))
                    Else
                        uniqueID = dtChangeRecord.Rows(0)("ID").ToString()
                    End If
                    If DatabaseHelper.GetSingle(String.Format(<stirng>SELECT 1 FROM sync_sendtoappid s WHERE s.parentid = '{0}'
                                                                    AND s.toappid = '{1}'</stirng>.Value, uniqueID, toAppId)) Is Nothing Then
                        arrList.Add(String.Format(insertSql2, uniqueID, toAppId))
                    End If
                Catch ex As Exception
                    Continue For
                End Try
            Next
        Else
            For Each row As DataRow In dtData.Rows
                Try
                    If String.IsNullOrWhiteSpace(row(uniqueColName).ToString()) Then
                        Continue For
                    End If
                    Dim sql = String.Format(<string>
                                    SELECT 1 FROM sync_tablechangerecord st
                                    LEFT JOIN sync_sendtoappid so ON so.parentid = st.id
                                    WHERE st.uniquecolvalue = '{0}' AND st.tablename = '{1}' AND st.operatetype = 1 AND so.toappid = '{2}'
                              </string>.Value, row(uniqueColName), tableName, toAppId)
                    If DatabaseHelper.GetSingle(sql) Is Nothing Then '查询数据是否有新增的记录，没有则不添加更新\删除记录
                        Continue For
                    End If
                    Dim uniqueID = Guid.NewGuid().ToString()
                    arrList.Add(String.Format(insertSql, uniqueID, tableName, uniqueColName, row(uniqueColName).ToString(), opType))
                    arrList.Add(String.Format(insertSql2, uniqueID, toAppId))
                Catch ex As Exception
                    Continue For
                End Try
            Next
        End If
        If isExcute Then
            If arrList.Count > 0 Then
                DatabaseHelper.ExecuteSqlTran(arrList)
            End If
            Return New ArrayList()
        End If
        Return arrList
    End Function

End Class
